package com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.css.fxfzfxqh.base.dict.service.DictItemService;
import com.css.fxfzfxqh.base.dict.service.DictService;
import com.css.fxfzfxqh.base.dict.viewobjects.DictEntityVo;
import com.css.fxfzfxqh.common.rest.JcsjRestManager;
import com.css.fxfzfxqh.common.rest.model.param.JcsjDataViewParam;
import com.css.fxfzfxqh.common.rest.model.vo.JcsjDataViewVo;
import com.css.fxfzfxqh.common.utils.CheckObjFields;
import com.css.fxfzfxqh.constants.FxfzConstants;
import com.css.fxfzfxqh.constants.YNEnum;
import com.css.fxfzfxqh.modules.buildingIndividual.entity.BuildingIndividualEntity;
import com.css.fxfzfxqh.modules.buildingIndividual.repository.BuildingIndividualRepository;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.StrategyFactoryException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.param.QueryByVersionParam;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.service.FxqhBuildingGridDataVersionService;
import com.css.fxfzfxqh.modules.buildings.VO.CurveVo;
import com.css.fxfzfxqh.modules.buildings.calculationTasks.entity.CalculationTasks;
import com.css.fxfzfxqh.modules.buildings.calculationTasks.entity.YSXMainTable;
import com.css.fxfzfxqh.modules.buildings.calculationTasks.repository.CalculationTasksRepository;
import com.css.fxfzfxqh.modules.buildings.calculationTasks.service.CalculationTasksService;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.entity.*;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.repository.CasualtiesDERepository;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.vo.CasualtiesCalculationVO;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.vo.Grid13VO;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.casualtiesDE.vo.PopulationBuildingIndividualVO;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.entity.PCCName;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.param.AssessParam;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.resistEarthquakesDE.vo.ResistEarthquakesPCCVO;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.economicLossPE.vo.EconomicLossPCCPEVO;
import com.css.fxfzfxqh.modules.population.service.PopulationService;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.entity.CasualtiesPE;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.entity.CasualtiesPECalculation;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.param.CasualtiesPECalculationParam;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.repository.CasualtiesPERepository;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.service.CasualtiesPEService;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.vo.CasualtiesPCCPEVO;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.casualtiesPE.vo.CasualtiesXYPEVO;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.entity.PsHazardDataValue;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.service.PublicOperateService;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.publicOperate.vo.BasicLibraryVo;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.resistEarthquakesPE.entity.ResistEarthquakesPE;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.resistEarthquakesPE.entity.ResistEarthquakesPECalculation;
import com.css.fxfzfxqh.modules.buildings.probabilityEvaluation.resistEarthquakesPE.repository.ResistEarthquakesPERepository;
import com.css.fxfzfxqh.modules.singleIndexRiskZoning.model.entity.FxqhAssessPdQhResult;
import com.css.fxfzfxqh.modules.util.ExcelUtil;
import com.css.fxfzfxqh.modules.util.ResistEarthquakesEnum;
import com.css.fxfzfxqh.modules.buildings.definitiveEvaluation.util.YSXEntity;
import com.css.fxfzfxqh.modules.util.hypergraph.service.HypergraphService;
import com.css.fxfzfxqh.modules.util.repository.PccRepository;
import com.css.fxfzfxqh.modules.util.repository.YSXRepository;
import com.css.fxfzfxqh.util.*;
import com.css.fxfzfxqh.web.PlatformSessionContext;
import com.css.fxfzfxqh.zcpt.sys.entity.SUser;
import com.css.fxfzfxqh.zcpt.sys.service.SUserService;
import com.css.fxfzfxqh.zcpt.sys.service.SysAreaService;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: zhangSongRui
 * @CreateTime: 2023/06/15
 * @Description: 人员伤亡概率评估Service
 */
@Service
public class CasualtiesPEServiceImpl implements CasualtiesPEService {

    @Resource
    ResistEarthquakesPERepository resistEarthquakesPERepository;
    @Resource
    private CasualtiesPERepository casualtiesPERepository;
    @Resource
    private SysAreaService sysAreaService;
    @Resource
    DictService dictService;
    @Resource
    SUserService sUserService;
    @Resource
    PccRepository pccRepository;
    @Resource
    private PublicOperateService publicOperateService;
    @Resource
    private YSXRepository ysxRepository;
    @Resource
    BuildingIndividualRepository buildingIndividualRepository;
    @Autowired
    DictItemService dictItemService;
    @Resource
    private FxqhBuildingGridDataVersionService fxqhBuildingGridDataVersionService;
    @Resource
    JcsjRestManager jcsjRestManager;
    @Resource
    private CasualtiesDERepository casualtiesDERepository;
    @Resource
    PopulationService populationService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    HypergraphService hypergraphService;
    @Resource
    CalculationTasksService calculationTasksService;
    @Resource
    private CalculationTasksRepository calculationTasksRepository;

    //新增评估记录
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void addAssess(CasualtiesPE param) {
        String user = sUserService.getSUser(PlatformSessionContext.getUserID());
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        param.setId(UUIDGenerator.getUUID());
        param.setCreateUser(sUser.getCreateUser());
        param.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
        param.setDelFlag(YNEnum.N.toString());
        //创建人单位
        param.setCompany(sUser.getOrgName());
        //写入省市县
        setCCP(param);
        casualtiesPERepository.addAssess(param);
    }

    //写入省市县
    private void setCCP(CasualtiesPE param) {
        List<PCC> pccList1 = new ArrayList<>();
        List<PCC> pccList = param.getList();
        if (pccList.size() != 0) {
            for (PCC pcc : pccList) {
                if (PlatformObjectUtils.isNotEmpty(pcc.getPpName())) {
                    if (PlatformObjectUtils.isEmpty(pcc.getCityName())) {
                        String childArea1 = sysAreaService.getChildAreaById(pcc.getPid());
                        List<PCCName> objects1 = JSON.parseArray(childArea1, PCCName.class);
                        for (PCCName pccName1 : objects1) {
                            String childArea2 = sysAreaService.getChildAreaById(pccName1.getId());
                            List<PCCName> objects2 = JSON.parseArray(childArea2, PCCName.class);
                            for (PCCName pccName2 : objects2) {
                                PCC pcc1 = new PCC();
                                pcc1.setAssessId(param.getId());
                                pcc1.setUuid(UUIDGenerator.getUUID());
                                pcc1.setPid(pcc.getPid());
                                pcc1.setPpName(pcc.getPpName());
                                pcc1.setCid(pccName1.getId());
                                pcc1.setCityName(pccName1.getName());
                                pcc1.setName(pccName2.getName());
                                pcc1.setId(pccName2.getId());
                                pccList1.add(pcc1);
                            }
                        }
                    } else {
                        if (PlatformObjectUtils.isEmpty(pcc.getName())) {
                            String childArea = sysAreaService.getChildAreaById(pcc.getCid());
                            List<PCCName> objects = JSON.parseArray(childArea, PCCName.class);
                            for (PCCName pccName : objects) {
                                PCC pcc1 = new PCC();
                                pcc1.setAssessId(param.getId());
                                pcc1.setUuid(UUIDGenerator.getUUID());
                                pcc1.setPid(pcc.getPid());
                                pcc1.setPpName(pcc.getPpName());
                                pcc1.setCid(pcc.getCid());
                                pcc1.setCityName(pcc.getCityName());
                                pcc1.setName(pccName.getName());
                                pcc1.setId(pccName.getId());
                                pccList1.add(pcc1);
                            }
                        } else {
                            pcc.setAssessId(param.getId());
                            pcc.setUuid(UUIDGenerator.getUUID());
                            pccList1.add(pcc);
                        }
                    }
                } else {
                    pcc.setAssessId(param.getId());
                    pcc.setUuid(UUIDGenerator.getUUID());
                    pccList1.add(pcc);
                }
            }
            pccRepository.batchSavePCC(pccList1);
        }
    }

    //根据id查询
    @Override
    public CasualtiesPE findById(String id) {
        CasualtiesPE byId = casualtiesPERepository.findById(id);
        List<PCC> list = pccRepository.queryToponym(byId.getId());
        byId.setList(list);
        return byId;
    }

    //修改评估记录
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void upDateAssess(CasualtiesPE param) {
        param.setUpdateUser(PlatformSessionContext.getUserID());
        param.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
        casualtiesPERepository.upDateAssess(param);
    }

    //获取评估编码
    @Override
    public String getCode(CasualtiesPE param) {
        //抗震能力确定评估
        StringBuilder code = new StringBuilder("JZW-RY-GL");
        if (param.getHouseDataFlag().equals("0")) {
            //单体
            code.append("-DT");
        } else if (param.getHouseDataFlag().equals("1")) {
            //网格
            code.append("-WG");
        }
        if (StringUtils.isEmpty(param.getCoordinateRange())) {
            //如果经纬度范围为空
            code.append("-QH");
        } else {
            code.append("-QD");
        }
        if (param.getSeismicInputMode().equals("0")) {
            //烈度
            code.append("-LD");
        } else if (param.getSeismicInputMode().equals("1")) {
            //概率水准
            code.append("-GL");
        } else if (param.getSeismicInputMode().equals("2")) {
            //地震影响场
            code.append("-YX");
        }
        String[] split1 = code.toString().split("-");
        if (split1.length != 6) {
            return code.toString();
        }
        //查询最近一次code
        String oldCode = casualtiesPERepository.queryLatest(code);
        if (StringUtils.isEmpty(oldCode)) {
            code.append("-0001");
        } else {
            String[] split = oldCode.split("-");
            code.append("-").append(getNext(split[6]));
        }
        return code.toString();
    }

    /****
     * 从哪里开始计数 比如startValue=2，则会从003,004,005等
     * @param startValue
     * @return
     */
    public String getNext(String startValue) {
        Integer i = Integer.valueOf(startValue);
        String format = String.format("%04d", i + 1);
        return format;
    }

    //分页查询
    @Override
    public Map<String, Object> getPage(int curPage, int pageSize, AssessParam param) {
        Map<String, Object> page = casualtiesPERepository.getPage(curPage, pageSize, param);
        List<CasualtiesPE> list = (List<CasualtiesPE>) page.get("rows");
        for (CasualtiesPE obj : list) {
            List<PCC> pccs = pccRepository.queryToponym(obj.getId());
            obj.setList(pccs);
        }
        page.put("rows", list);
        return page;
    }

    //根据版本获取人口格网数据并将人口和extends1进行关联
    private Map<String, BigDecimal> getPopMap(List<LinkedHashMap> popoluationList) throws Exception {
        Map<String, BigDecimal> popMap = new HashMap<>();
        for (LinkedHashMap lm : popoluationList) {
            //常驻人口数据
            Object tzl3 = lm.get("tzl3");
            BigDecimal personNum = BigDecimal.ZERO;
            if (PlatformObjectUtils.isNotEmpty(tzl3)) {
                personNum = new BigDecimal(tzl3.toString());
            }
            Object extends1 = lm.get("extends1");
            if (PlatformObjectUtils.isNotEmpty(extends1)) {
                popMap.put(extends1.toString(), personNum);
            } else {
                continue;
            }
        }
        return popMap;
    }

    //计算值
//    @Override
//    public void calculation(String assessId,String years) throws Exception {
//        casualtiesPERepository.deleteEvaluateResult(assessId);
//        Long start = System.currentTimeMillis();
//        Map<String,Map<String, BasicLibraryVo>> disrictMap = new HashMap<>();
//        Map<String,Map<String, List<BigDecimal>>> disrictYsxMap = new HashMap<>();
//        //获取评估记录信息
//        ResistEarthquakesPE casualtiesPE = resistEarthquakesPERepository.findById(assessId);
//        //房屋基础数据选择方式
//        String houseDataFlag = casualtiesPE.getHouseDataFlag();
//        //radio2:0为省市区县1为地图圈选
//        String radio2 = casualtiesPE.getRadio2();
//        String geom = "";
//        if("0".equals(radio2)){
//            List<PCC> list = pccRepository.queryToponym(assessId);
//            geom = publicOperateService.getUnionGeomByCode(list);
//        }else if("1".equals(radio2)){
//            geom = casualtiesPE.getGeom();
//        }
//        //获取人口格网数据
//        List<LinkedHashMap> popoluationList = getPopoluationList(casualtiesPE.getPopluationVersion(), null);
//        if(PlatformObjectUtils.isEmpty(popoluationList) || popoluationList.size()==0){
//            throw new RuntimeException("计算未完成,人口格网版本为"+casualtiesPE.getPopluationVersion()+"下没有人口格网数据");
//        }
//        //破坏程度的集合
//        List<String> detoryList = getDetoryList();
//        List<CasualtiesPECalculation> result = new ArrayList<>();
//        if(org.apache.commons.lang3.StringUtils.isNotBlank(geom)){
//            //发生概率危险性数据
//            //0：pga,1：烈度
//            String risk = casualtiesPE.getRisk();
//            List<PsHazardDataValue> psHazardDataValueList = publicOperateService.getPsHazardDataValueList(risk, geom);
//            Table<String, List<String>, List<BigDecimal>> table = publicOperateService.buildPsHazardDataValue(psHazardDataValueList);
//            if(psHazardDataValueList.size()>0){
//                //根据版本获取人口格网数据并将人口和extends1进行关联
//                Map<String, BigDecimal> popMap = getPopMap(popoluationList);
//                //使用的是房屋格网数据
//                if("1".equals(houseDataFlag)){
//                    List<DictEntityVo> dictItemByDictId = dictItemService.getDictItemByDictId("jzwglgwlx");
//                    //Map<String, List<PsHazardDataValue>> kiloMap = psHazardDataValueList.stream().collect(Collectors.groupingBy(PsHazardDataValue::getKilometerGridId));
//                    List<String> kilometerGridIds = psHazardDataValueList.stream().map(PsHazardDataValue::getKilometerGridId).distinct().collect(Collectors.toList());
//                    for (String kilometerGridId : kilometerGridIds) {
//                        String province="",city="",county="";
//                        String geographyId = kilometerGridId;
//                        //获取发生概率危险性的X（im或烈度）数据
//                        List<String> damageList = getDamageXList(table,kilometerGridId);
//                        //13张表数据同属于一个完整格网的白天或夜晚的重伤的数据
//                        Table<Integer,String,BigDecimal>  mhTable = HashBasedTable.create();
//                        //13张表数据同属于一个完整格网的白天或夜晚的死亡的数据
//                        Table<Integer,String,BigDecimal>  mdTable = HashBasedTable.create();
//                        //13张表数据同属于一个完整格网的总面积
//                        BigDecimal totalAreaAll = BigDecimal.ZERO;
//                        BigDecimal popNum = popMap.get(kilometerGridId);
//                        if(popNum==null){
//                            continue;
//                        }
//                        int flag = 0;
//                        //循环遍历获取13张房屋网格数据
//                        for (DictEntityVo vo : dictItemByDictId) {
//                            //获取13张房屋网格数据
//                            List<Grid13VO> jggwList = get13GridList(kilometerGridId,vo,casualtiesPE.getHouseData());
//                            if(PlatformObjectUtils.isEmpty(jggwList) || jggwList.size()==0){
//                                continue;
//                            }
//                            //如果房屋网格数据准确的话，一条psHazardDataValue数据根据extends1字段每次只会检索出一条格网数据
//                            Grid13VO obj = jggwList.get(0);
//                            province = obj.getProvince();city = obj.getCity();county = obj.getCounty();
//                            totalAreaAll = totalAreaAll.add(new BigDecimal(obj.getTotalArea()));
//                            //判断网格的房屋用途并返回各自所占的面积  如1-100.00  1表示是第几类房屋用途 100.00表示是该类房屋用途的面积
//                            List<String> houseUsingAreaList = getHouseUsingArea(obj);
//                            //设防烈度
//                            List<String> sfIntensityList = getIntensityList(obj);
//                            //获取房屋格网的设防情况 并返回各自所占的比例
//                            Map<String, BigDecimal> intensitArea = getIntensitArea(obj);
//                            //白天 夜晚
//                            for(Integer datePeriod:getDayPeriod()){
//                                //破坏程度(轻微破坏~损坏)
//                                for (String destroyDegree : detoryList) {
//                                    int num = 0;
//                                    //totalMh 表示在白天或黑夜 某中破坏状态下的重伤人数
//                                    BigDecimal totalMh = BigDecimal.ZERO;
//                                    //totalMd 表示在白天或黑夜 某中破坏状态下的死亡人数
//                                    BigDecimal totalMd = BigDecimal.ZERO;
//                                    //破坏程度与对应的重伤比
//                                    BigDecimal rh = getInjureMap().get(destroyDegree);
//                                    //破坏程度与对应的死亡比
//                                    BigDecimal rd = getDeathMap().get(destroyDegree);
//                                    //发生概率地震危险性X值(VI或0.01) 如0.01
//                                    for (String damage : damageList) {
//                                        //设防烈度 如未设防
//                                        for (String sfIntensity : sfIntensityList) {
//                                            //不同设防情况面积占比
//                                            BigDecimal ratio = intensitArea.get(sfIntensity);
//                                            //获取到的函数值
//                                            BigDecimal funtionValue = BigDecimal.ZERO;
//                                            if("0".equals(risk)){
//                                                //pga数据
//                                                funtionValue = getFuntionValue(obj,sfIntensity,destroyDegree,damage,null,null,disrictMap);
//                                            }else if("1".equals(risk)){
//                                                //烈度数据
//                                                funtionValue = getIdFuntionValue(obj,sfIntensity,destroyDegree,damage,null,null,disrictYsxMap);
//                                            }
//                                            //房屋用途（三类房屋用途）
//                                            for (String houseUsingArea : houseUsingAreaList) {
//                                                num++;
//                                                //房屋用途编号  （第一类1、第二类2、第三类3）
//                                                String houseUsingIndex = houseUsingArea.split("-")[0];
//                                                //房屋用途对应的面积
//                                                String area = houseUsingArea.split("-")[1];
//                                                //室内人员昼夜在三类结构中的的百分比
//                                                List<BigDecimal> ratioByStructureCategory = getRatioByStructureCategory(houseUsingIndex);
//                                                //房屋用途在白天和夜晚下人员在室内的百分比
//                                                BigDecimal C = ratioByStructureCategory.get(datePeriod);
//                                                //三类房屋用途在不同设防情况下的占比面积
//                                                BigDecimal sfArea = new BigDecimal(area).multiply(ratio.divide(BigDecimal.valueOf(100),6,RoundingMode.HALF_DOWN));
//                                                //A4（0.01）=S(砖混)*易损性值（0.01、砖混、轻微破坏）
//                                                BigDecimal a4 = sfArea.multiply(funtionValue);
//                                                //Mh(I、0.01)=C*η*A4（0.01）*rh4)   Mh是不同破坏状态下的人员受伤情况
//                                                BigDecimal mh = C.multiply(a4).multiply(rh);
//                                                BigDecimal md = C.multiply(a4).multiply(rd);
//                                                totalMh = totalMh.add(mh);
//                                                totalMd = totalMd.add(md);
//                                            }
//                                        }
//                                    }
//                                    BigDecimal mhTatal = mhTable.get(datePeriod, destroyDegree);
//                                    if(mhTatal!=null && mhTatal.compareTo(BigDecimal.ZERO)>0){
//                                        BigDecimal newResult = totalMh.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mhTatal = mhTatal.add(newResult);
//                                        mhTable.put(datePeriod,destroyDegree,mhTatal);
//                                    }else{
//                                        BigDecimal newResult = totalMh.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mhTable.put(datePeriod,destroyDegree,newResult);
//                                    }
//                                    BigDecimal mdTatal = mdTable.get(datePeriod, destroyDegree);
//                                    if(mdTatal!=null && mdTatal.compareTo(BigDecimal.ZERO)>0){
//                                        BigDecimal newResult = totalMd.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mdTatal = mdTatal.add(newResult);
//                                        mdTable.put(datePeriod,destroyDegree,mdTatal);
//                                    }else{
//                                        BigDecimal newResult = totalMd.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mdTable.put(datePeriod,destroyDegree,newResult);
//                                    }
//                                }
//                            }
//                            flag = 1;
//                        }
//                        if(flag>0){
//                            //η—房屋内人员的密度
//                            BigDecimal η = BigDecimal.ZERO;
//                            if(totalAreaAll.compareTo(BigDecimal.ZERO)>0){
//                                η = popNum.divide(totalAreaAll, 6, RoundingMode.HALF_DOWN);
//                            }
//                            //<0/1,<破坏程度，人员重伤数>
//                            Map<Integer, Map<String, BigDecimal>> injureMap = mhTable.rowMap();
//                            BigDecimal finalη = η;
//                            String finalProvince = province;
//                            String finalCity = city;
//                            String finalCounty = county;
//                            String finalGeographyId = geographyId;
//                            String finalExtends1 = kilometerGridId;
//                            //白天或黑夜下的几种破坏程度的重伤人数
//                            injureMap.forEach((k, v) ->{
//                                //k是白天（1）和黑夜（0），v是<破坏程度，人员重伤数量>
//                                v.forEach((a, b) -> {
//                                    //a是破坏程度 b是重伤数量
//                                    b = b.multiply(finalη);
//                                    CasualtiesPECalculation calculation = getCasualtiesPECalculation(years, casualtiesPE, finalProvince, finalCity, finalCounty, finalGeographyId, k, a, b, "1",finalExtends1);
//                                    result.add(calculation);
//                                });
//                            });
//                            //<0/1,<破坏程度，人员重伤数>
//                            Map<Integer, Map<String, BigDecimal>> deathMap = mdTable.rowMap();
//                            //白天或黑夜下的几种破坏程度的死亡人数
//                            deathMap.forEach((k, v) ->{
//                                //k是白天（1）和黑夜（0），v是<破坏程度，人员重伤数量>
//                                v.forEach((a, b) -> {
//                                    //a是破坏程度 b是重伤数量
//                                    b = b.multiply(finalη);
//                                    CasualtiesPECalculation calculation = getCasualtiesPECalculation(years, casualtiesPE, finalProvince, finalCity, finalCounty, finalGeographyId, k, a, b, "2",finalExtends1);
//                                    result.add(calculation);
//                                });
//                            });
//                        }
//                    }
//                }else{
//                    //使用的是房屋单体数据数据
//                    //查询字典项
//                    Map<Object, Object> map = redisTemplate.opsForHash().entries("FXQH:" + FxfzConstants.CACHE_SYS_KEY + "dictItemMapForEvaluate");
//                    if(map==null || map.values().size()==0){
//                        map = dictItemService.getDictItemMap();
//                    }
//
//                    Map<String,BigDecimal> popGridMap = buildGridMap(popoluationList,casualtiesPE.getHouseData());
//                    for (PsHazardDataValue psHazardDataValue : psHazardDataValueList) {
//                        List<BuildingIndividualEntity> buildingIndividualVOs = publicOperateService.getBuildingIndividualVOs(psHazardDataValue.getGeom(), casualtiesPE.getHouseData());
//                        if(PlatformObjectUtils.isNotEmpty(buildingIndividualVOs) && buildingIndividualVOs.size()>0){
//                            //获取发生概率危险性的X（im或烈度）数据
//                            List<String> damageList = getDamageXList(table,psHazardDataValue.getKilometerGridId());
//                            for (BuildingIndividualEntity entity : buildingIndividualVOs) {
//                                BigDecimal percent = popGridMap.get(entity.getBuildingCode());
//                                if(percent==null){
//                                    percent = BigDecimal.ZERO;
//                                }
//                                String area = entity.getArea();
//                                BigDecimal η = BigDecimal.ZERO;
//                                if(org.apache.commons.lang3.StringUtils.isNotBlank(area)){
//                                    //室内人口密度
//                                    η = percent.multiply(new BigDecimal(area));
//                                }
//                                //设防情况
//                                String sfIntensity = entity.getDefenceLevel();
//
//                                if(org.apache.commons.lang3.StringUtils.isNotBlank(sfIntensity)){
//                                    //如果烈度是5度则按照6度来算，如果是11和12度则按照10度来算
//                                    if("5".equals(sfIntensity)){
//                                        sfIntensity = "6度";
//                                    }else if("11".equals(sfIntensity)){
//                                        sfIntensity = "10度";
//                                    }else if("12".equals(sfIntensity)){
//                                        sfIntensity = "10度";
//                                    }else{
//                                        sfIntensity += "度";
//                                    }
//                                }
//                                //白天 夜晚
//                                for(Integer datePeriod:getDayPeriod()){
//                                    //破坏程度(轻微破坏~损坏)
//                                    for (String destroyDegree : detoryList) {
//                                        //totalMh 表示在白天或黑夜 某中破坏状态下的重伤人数
//                                        BigDecimal totalMh = BigDecimal.ZERO;
//                                        //totalMd 表示在白天或黑夜 某中破坏状态下的死亡人数
//                                        BigDecimal totalMd = BigDecimal.ZERO;
//                                        //破坏程度与对应的重伤比
//                                        BigDecimal rh = getInjureMap().get(destroyDegree);
//                                        //破坏程度与对应的死亡比
//                                        BigDecimal rd = getDeathMap().get(destroyDegree);
//                                        //发生概率地震危险性X值(VI或0.01) 如0.01
//                                        for (String damage : damageList) {
//                                            //设防烈度 如未设防
//                                            //获取到的函数值
//                                            BigDecimal funtionValue = BigDecimal.ZERO;
//                                            if("0".equals(risk)){
//                                                //pga数据
//                                                funtionValue = getFuntionValue(null,sfIntensity,destroyDegree,damage,entity,map,disrictMap);
//                                            }else if("1".equals(risk)){
//                                                //烈度数据
//                                                funtionValue = getIdFuntionValue(null,sfIntensity,destroyDegree,damage,entity,map,disrictYsxMap);
//                                            }
//                                            //室内人员昼夜在三类结构中的的百分比
//                                            List<BigDecimal> ratioByStructureCategory = getRatioByStructureCategory(entity.getUsage1());
//                                            //房屋用途在白天和夜晚下人员在室内的百分比
//                                            BigDecimal C = ratioByStructureCategory.get(datePeriod);
//                                            //三类房屋用途在不同设防情况下的占比面积
//                                            BigDecimal sfArea = org.apache.commons.lang3.StringUtils.isBlank(entity.getArea())?BigDecimal.ZERO:new BigDecimal(entity.getArea());
//                                            //A4（0.01）=S(砖混)*易损性值（0.01、砖混、轻微破坏）
//                                            BigDecimal a4 = sfArea.multiply(funtionValue);
//                                            //Mh(I、0.01)=C*η*A4（0.01）*rh4)   Mh是不同破坏状态下的人员受伤情况
//                                            BigDecimal mh = C.multiply(a4).multiply(rh).multiply(η);
//                                            BigDecimal md = C.multiply(a4).multiply(rd).multiply(η);
//                                            totalMh = totalMh.add(mh).setScale(6,RoundingMode.HALF_DOWN);
//                                            totalMd = totalMd.add(md).setScale(6,RoundingMode.HALF_DOWN);
//                                        }
//                                        //重伤数据
//                                        CasualtiesPECalculation injureCalculation = getCasualtiesPECalculation(years, casualtiesPE, entity.getProvince(), entity.getCity(), entity.getCounty(), entity.getId(), datePeriod, destroyDegree, totalMh, "1","");
//                                        result.add(injureCalculation);
//                                        //死亡数据
//                                        CasualtiesPECalculation deathCalculation = getCasualtiesPECalculation(years, casualtiesPE, entity.getProvince(), entity.getCity(), entity.getCounty(), entity.getId(), datePeriod, destroyDegree, totalMd, "2","");
//                                        result.add(deathCalculation);
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        if(result.size()>0){
//            //查询抗震能力的计算结果
//            getPtValueAndSave(result,casualtiesPE.getId(),years);
//        }
//        //boolean bool = hypergraphService.getWorkspaceReload("fxqh_casualties_calculation_pd");
//        Long end =System.currentTimeMillis();
//        System.out.println("时间消耗:"+(end-start)/1000);
//    }

    private Map<String,Integer> buildDamageSortMap(){
        Map<String,Integer> map = new HashMap<>();
        map.put("基本完好",1);
        map.put("轻微破坏",2);
        map.put("中等破坏",3);
        map.put("严重破坏",4);
        map.put("毁坏",5);
        map.put("倒塌",6);
        return map;
    }

    /**
     * 获取区域的空间数据
     */
    private String getGeom(CalculationTasks calculationTasks ) throws Exception {
        //radio2:0为省市区县1为地图圈选
        if ("0".equals(calculationTasks.getRadio2())) {
            List<PCC> list = pccRepository.queryToponym(calculationTasks.getId());
            return publicOperateService.getUnionGeomByCode(list);
        }
        return calculationTasks.getCoordinateRange();
    }
    /**
     * 获取并组建人口格网数据
     */
    private List<LinkedHashMap> getPopData(CalculationTasks calculationTasks) throws Exception {
        //获取人口格网数据
        List<LinkedHashMap> popoluationList = getPopoluationList(calculationTasks.getPopluationVersion(), null);
        if (PlatformObjectUtils.isEmpty(popoluationList) || popoluationList.size() == 0) {
            throw new RuntimeException("计算未完成,人口格网版本为" + calculationTasks.getPopluationVersion() + "下没有人口格网数据");
        }
        //根据版本获取人口格网数据并将人口和extends1进行关联
        return popoluationList;
    }
    /**
     * 将0.04g	0.09g	0.19g	0.38g	0.75g转换成对应的烈度
     */
    private String getRealIntensity(String intensity){
        switch (intensity){
            case "0.04g":
                return "6度";
            case "0.09g":
                return "7度";
            case "0.19g":
                return "8度";
            case "0.38g":
                return "9度";
            case "0.75g":
                return "10度";
            default: return "";
        }
    }
    private Table<String, List<String>, List<BigDecimal>> getProbabilisticTable(CalculationTasks calculationTasks,String geom,String type) throws BizException {
        //type 0:网格;1:单体;
        Table<String, List<String>, List<BigDecimal>> table = null;
        String risk = calculationTasks.getLdPga();
        //超越概率危险性
        if ("4".equals(calculationTasks.getSeismicInputMode())) {
            table = publicOperateService.transition1(geom, calculationTasks.getBeyondProbabilisticVersion(), type);
        } else if ("3".equals(calculationTasks.getSeismicInputMode())) {
            //发生概率危险性
            List<PsHazardDataValue> psHazardDataValueList = publicOperateService.getPsHazardDataValueList1(risk, geom,calculationTasks);
            table = publicOperateService.buildPsHazardDataValue2(psHazardDataValueList,type);
        }
        return table;
    }
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void calculation(String taskId,String year) throws Exception {
        Map<String,BigDecimal> functionMap = new HashMap<>();
        //获取评估记录信息
        CalculationTasks calculationTasks = calculationTasksService.findById(taskId);
        //删除评估记录之前生成的数据
        casualtiesPERepository.deleteEvaluateResult(taskId);
        String years = calculationTasks.getYear();
        Long start = System.currentTimeMillis();
        //组建数据格式
        Map<String, Map<String, Map<String, BigDecimal>>> pgaMap = new HashMap<>();
        Map<String, Map<String, List<YSXMainTable>>> ldMap = new HashMap<>();
        //获取网格中各结构类型不同房屋用途占比（备用如果原房屋格网中各个房屋用途占比均为0但是总面积不为0时使用）
        List<StructureHouseUsingPercent> percentList = casualtiesDERepository.getStructureHouseUsingPercent();
        //房屋基础数据选择方式
        String houseDataFlag = calculationTasks.getHouseDataFlag();
        //获取并组建人口格网数据
        List<LinkedHashMap> popoluationList = getPopData(calculationTasks);
        //破坏程度的集合
        List<String> detoryList = getDetoryList();
        List<CasualtiesPECalculation> result = new ArrayList<>();
        //获取区域的空间数据
        String geom = getGeom(calculationTasks);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(geom)) {
            //1：pga,0：烈度
            String risk = calculationTasks.getLdPga();;
            Table<String, List<String>, List<BigDecimal>> table = null;
            //使用的是房屋格网数据
            if ("1".equals(houseDataFlag)) {
                Map<String, BigDecimal> popMap = getPopMap(popoluationList);
                //获取并组建指定格式的危险性数据
                table = getProbabilisticTable(calculationTasks,geom,houseDataFlag);
                List<Grid13VO> jggwList1 = calculationTasksRepository.getLdDate(calculationTasks.getId(), "", "");
                if(PlatformObjectUtils.isNotEmpty(jggwList1) &&jggwList1.size()>0){
                    //获取相同格网id的13不同建筑物结构的数据
                    Map<String, List<Grid13VO>> sameIdGridMap = jggwList1.stream().filter(grid13VO -> org.apache.commons.lang3.StringUtils.isNotBlank(grid13VO.getExtends1())).collect(Collectors.groupingBy(Grid13VO::getExtends1));
                    Iterator<Map.Entry<String, List<Grid13VO>>> iterator = sameIdGridMap.entrySet().iterator();
                    while(iterator.hasNext()){
                        Map.Entry<String, List<Grid13VO>> next = iterator.next();
                        String extends1 = next.getKey();
                        //同一个格网id的13类建筑物数据
                        List<Grid13VO> values = next.getValue();
                        String province = values.get(0).getProvince(), city = values.get(0).getCity(), county = values.get(0).getCounty();
                        //获取单元格总面积
                        double totalAreaAll = values.stream().mapToDouble(Grid13VO::getTotalArea).sum();
                        //获取单元格总人口
                        BigDecimal totalPopulation = popMap.get(extends1);
                        //13张表数据同属于一个完整格网的白天或夜晚的重伤的数据
                        Table<String, String, BigDecimal> mhTable = HashBasedTable.create();
                        //13张表数据同属于一个完整格网的白天或夜晚的死亡的数据
                        Table<String, String, BigDecimal> mdTable = HashBasedTable.create();
                        //获取发生概率危险性的X（im或烈度）数据
                        Map<List<String>, List<BigDecimal>> row = table.row(extends1);
                        List<String> damageList = getDamageXList(row);
                        List<BigDecimal> valueList = getDamageValList(row);
                        String geomVal = "";
                        for (Grid13VO obj : values) {
                            if("".equals(geomVal)){
                                geomVal = obj.getGeom() ;
                            }
                            //结构类型_设防情况,<破坏程度，mr,br>
                            Map<String, Map<String, BigDecimal>> mapTable = null;
                            Map<String, List<YSXMainTable>> ysxMap = null;
                            if ("1".equals(risk)) {
                                //获取省市县的易损性数据 结果格式形如<省市县 <结构类型_设防情况  <破坏程度，mr，br>>>
                                mapTable = handlePageOfYsx(obj.getProvince(), obj.getCity(), obj.getCounty(), pgaMap,calculationTasks.getYsxVersion(),calculationTasks.getId());
                            } else if ("0".equals(risk)) {
                                ysxMap = handleYsx1(obj.getProvince(), obj.getCity(), obj.getCounty(), ldMap,taskId);
                            }
                            //判断网格的房屋用途并返回各自所占的面积  如1-100.00  1表示是第几类房屋用途 100.00表示是该类房屋用途的面积
                            List<String> houseUsingAreaList = getHouseUsingArea(obj,percentList);
                            //设防烈度
                            List<String> sfIntensityList = getIntensityList(obj);
                            //获取房屋格网的设防情况 并返回各自所占的比例
                            Map<String, BigDecimal> intensitArea = getIntensitArea(obj);
                            //白天 夜晚
                            for (Integer datePeriod : getDayPeriod()) {
                                //破坏程度(轻微破坏~损坏)
                                for (String destroyDegree : detoryList) {
                                    //totalMh 表示在白天或黑夜 某中破坏状态下的重伤人数
                                    BigDecimal totalMh = BigDecimal.ZERO;
                                    //totalMd 表示在白天或黑夜 某中破坏状态下的死亡人数
                                    BigDecimal totalMd = BigDecimal.ZERO;
                                    //破坏程度与对应的重伤比
                                    BigDecimal rh = getInjureMap().get(destroyDegree);
                                    //破坏程度与对应的死亡比
                                    BigDecimal rd = getDeathMap().get(destroyDegree);
                                    //发生概率地震危险性X值 （0.04g	0.09g	0.19g	0.38g	0.75g）即地震烈度
                                    for (int i=0;i<damageList.size();i++) {
                                        String damage = damageList.get(i);
                                        BigDecimal fVal = valueList.get(i);
                                        //将0.04g	0.09g	0.19g	0.38g	0.75g转换成对应的烈度
//                                        String realIntensity = getRealIntensity(damage);
                                        String realIntensity = damage;
                                        //设防烈度 如未设防
                                        for (String sfIntensity : sfIntensityList) {
                                            //不同设防情况面积占比
                                            BigDecimal ratio = intensitArea.get(sfIntensity);
                                            //获取到的易损性函数值  如地震烈度为6度 设防烈度为未设防的概率危险性的值
                                            BigDecimal funtionValue = BigDecimal.ZERO;
                                            //结构类型
                                            String structure = getStructure(obj, null, null);

                                            if ("1".equals(risk)) {
                                                //pga数据
                                                funtionValue = getFunctionValue(structure, mapTable, destroyDegree, realIntensity, sfIntensity,functionMap);
                                                if(funtionValue == null){
                                                    continue;
                                                }
                                                fVal = BigDecimal.ONE;
                                            } else if ("0".equals(risk)) {
                                                //烈度数据
                                                String intensity = getRealIntensity(realIntensity);
                                                funtionValue = getIdFuntionValue(structure, sfIntensity, destroyDegree, intensity, ysxMap);
                                                if(funtionValue == null){
                                                    continue;
                                                }
                                            }
                                            //房屋用途（三类房屋用途）
                                            for (String houseUsingArea : houseUsingAreaList) {
                                                //房屋用途编号  （第一类1、第二类2、第三类3）
                                                String houseUsingIndex = houseUsingArea.split("-")[0];
                                                //房屋用途对应的面积
                                                String area = houseUsingArea.split("-")[1];
                                                //室内人员昼夜在三类结构中的的百分比
                                                List<BigDecimal> ratioByStructureCategory = getRatioByStructureCategory(houseUsingIndex);
                                                //房屋用途在白天和夜晚下人员在室内的百分比
                                                BigDecimal C = ratioByStructureCategory.get(datePeriod);
                                                //三类房屋用途在不同设防情况下的占比面积
                                                BigDecimal sfArea = new BigDecimal(area).multiply(ratio.divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                                                //A4（0.01）=S(砖混)*易损性值（0.01、砖混、轻微破坏）
                                                BigDecimal a4 = sfArea.multiply(funtionValue).multiply(fVal);
                                                //Mh(I、0.01)=C*η*A4（0.01）*rh4)   Mh是不同破坏状态下的人员受伤情况
                                                BigDecimal mh = C.multiply(a4).multiply(rh);
                                                BigDecimal md = C.multiply(a4).multiply(rd);
                                                totalMh = totalMh.add(mh);
                                                totalMd = totalMd.add(md);
                                            }
                                        }
                                    }
                                    //重伤
                                    BigDecimal mhTatal = mhTable.get(datePeriod+ "" , destroyDegree);
                                    if (mhTatal != null && mhTatal.compareTo(BigDecimal.ZERO) > 0) {
                                        BigDecimal newResult = totalMh.setScale(6, BigDecimal.ROUND_DOWN);
                                        mhTatal = mhTatal.add(newResult);
                                        mhTable.put(datePeriod+"" , destroyDegree, mhTatal);
                                    } else {
                                        BigDecimal newResult = totalMh.setScale(6, BigDecimal.ROUND_DOWN);
                                        mhTable.put(datePeriod + "" , destroyDegree, newResult);
                                    }
                                    //死亡
                                    BigDecimal mdTatal = mdTable.get(datePeriod + "" , destroyDegree);
                                    if (mdTatal != null && mdTatal.compareTo(BigDecimal.ZERO) > 0) {
                                        BigDecimal newResult = totalMd.setScale(6, BigDecimal.ROUND_DOWN);
                                        mdTatal = mdTatal.add(newResult);
                                        mdTable.put(datePeriod + "" , destroyDegree, mdTatal);
                                    } else {
                                        BigDecimal newResult = totalMd.setScale(6, BigDecimal.ROUND_DOWN);
                                        mdTable.put(datePeriod + "" , destroyDegree, newResult);
                                    }
                                }
                            }
                        }
                        //η—房屋内人员的密度
                        BigDecimal η = BigDecimal.ZERO;
                        if (new BigDecimal(totalAreaAll).compareTo(BigDecimal.ZERO) > 0) {
                               η = totalPopulation.divide(new BigDecimal(totalAreaAll), 6, RoundingMode.HALF_DOWN);
                        }
                        //<0/1,<破坏程度，人员重伤数>
                        Map<String, Map<String, BigDecimal>> injureMap = mhTable.rowMap();
                        BigDecimal finalη = η;
                        String finalProvince = province;
                        String finalCity = city;
                        String finalCounty = county;
                        String finalGeographyId = extends1;
                        String finalExtends1 = extends1;
                        //白天或黑夜下的几种破坏程度的重伤人数
                        String finalGeomVal = geomVal;
                        injureMap.forEach((k, v) -> {
                            //k是白天（1）和黑夜（0）- 空间数据，v是<破坏程度，人员重伤数量>
                            String k1 = k.split("-")[0];
                            //空间数据
                            String k2 = finalGeomVal;
                            List<CasualtiesPECalculation> tempList = new ArrayList<>();
                            v.forEach((a, b) -> {
                                //a是破坏程度 b是重伤数量
                                b = b.multiply(finalη);
                                CasualtiesPECalculation calculation = getCasualtiesPECalculation(years, calculationTasks, finalProvince, finalCity, finalCounty, finalGeographyId, k1, k2, a, b, "rysw1", finalExtends1);
                                Integer sort = buildDamageSortMap().get(a);
                                calculation.setSort(sort);
                                tempList.add(calculation);
                            });
                            result.addAll(tempList);
//                            BigDecimal result2 = tempList.stream()
//                                    // 将user对象的age取出来map为Bigdecimal
//                                    .map(CasualtiesPECalculation::getCorrectionValue)
//                                    // 使用reduce()聚合函数,实现累加器
//                                    .reduce(BigDecimal.ZERO,BigDecimal::add);
//                            tempList.forEach(calculation->{
//                                calculation.setExpectValue(result2);
//                                result.add(calculation);
//                            });
                        });
                        //<0/1,<破坏程度，人员重伤数>
                        Map<String, Map<String, BigDecimal>> deathMap = mdTable.rowMap();
                        //白天或黑夜下的几种破坏程度的死亡人数
                        String finalGeomVal1 = geomVal;
                        deathMap.forEach((k, v) -> {
                            //k是白天（1）和黑夜（0）- 空间数据，v是<破坏程度，人员重伤数量>
                            String k1 = k.split("-")[0];
                            //空间数据
                            String k2 = finalGeomVal1;
                            List<CasualtiesPECalculation> tempList = new ArrayList<>();
                            v.forEach((a, b) -> {
                                //a是破坏程度 b是重伤数量
                                b = b.multiply(finalη);
                                CasualtiesPECalculation calculation = getCasualtiesPECalculation(years, calculationTasks, finalProvince, finalCity, finalCounty, finalGeographyId, k1, k2, a, b, "rysw2", finalExtends1);
                                Integer sort = buildDamageSortMap().get(a);
                                calculation.setSort(sort);
                                tempList.add(calculation);
                            });
                            //List<CasualtiesPECalculation> sortedList = tempList.stream().sorted(Comparator.comparing(CasualtiesPECalculation::getSort)).collect(Collectors.toList());
//                            BigDecimal result2 = tempList.stream()
//                                    // 将user对象的age取出来map为Bigdecimal
//                                    .map(CasualtiesPECalculation::getCorrectionValue)
//                                    // 使用reduce()聚合函数,实现累加器
//                                    .reduce(BigDecimal.ZERO,BigDecimal::add);
//                            tempList.forEach(calculation->{
//                                calculation.setExpectValue(result2);
//                                result.add(calculation);
//                            });
                            result.addAll(tempList);
                        });
                    }

                }
            } else {
                //使用的是房屋单体数据数据
                //查询字典项
                Map<Object, Object> dictMap = redisTemplate.opsForHash().entries("FXQH:" + FxfzConstants.CACHE_SYS_KEY + "dictItemMapForEvaluate");
                if (dictMap == null || dictMap.values().size() == 0) {
                    dictMap = dictItemService.getDictItemMap();
                }
                //获取任务空间区域内的概率危险性数据
                table = getProbabilisticTable(calculationTasks,geom,risk);
                //获取房屋单体房屋内人员的密度
                Map<String, BigDecimal> popGridMap = buildGridMap(popoluationList, calculationTasks.getHouseData());
                if (table != null) {
                    Set<String> geomList = table.rowKeySet();
                    //for (PsHazardDataValue psHazardDataValue : psHazardDataValueList) {
                    for (String geom1 : geomList) {
                        //获取建筑物单体数据
                        List<BuildingIndividualEntity> buildingIndividualVOs = publicOperateService.getBuildingIndividualVOs(geom1, calculationTasks.getHouseData());
                        if (PlatformObjectUtils.isNotEmpty(buildingIndividualVOs) && buildingIndividualVOs.size() > 0) {
                            //获取发生概率危险性的数据
                            Map<List<String>, List<BigDecimal>> row = table.row(geom1);
                            //0.04g	0.09g	0.19g	0.38g	0.75g
                            List<String> damageList = getDamageXList(row);
                            //0.04g	0.09g	0.19g	0.38g	0.75g各自对应的value值
                            List<BigDecimal> valueList = getDamageValList(row);
                            for (BuildingIndividualEntity entity : buildingIndividualVOs) {
                                //房屋单体房屋内人员的密度中间值
                                BigDecimal percent = popGridMap.get(entity.getBuildingCode());
                                if (percent == null) {
                                    percent = BigDecimal.ZERO;
                                }
                                //单体面积
                                String area = entity.getArea();
                                //房屋单体房屋内人员的密度
                                BigDecimal η = percent.multiply(new BigDecimal(area));

                                //结构类型_设防情况_烈度,<破坏程度，mr,br>
                                Map<String, Map<String, BigDecimal>> mapTable = null;
                                Map<String, List<YSXMainTable>> ysxMap = null;
                                if ("1".equals(risk)) {
                                    //pga
                                    //获取省市县的易损性数据 结果格式形如<省市县 <结构类型_设防情况  <破坏程度，mr，br>>>
                                    mapTable = handlePageOfYsx(entity.getProvince(), entity.getCity(), entity.getCounty(), pgaMap,calculationTasks.getYsxVersion(),calculationTasks.getId());
                                } else if ("0".equals(risk)) {
                                    //烈度
                                    ysxMap = handleYsx1(entity.getProvince(), entity.getCity(), entity.getCounty(), ldMap,taskId);
                                }

                                //设防情况
                                String sfIntensity = entity.getDefenceLevel();
                                if (org.apache.commons.lang3.StringUtils.isNotBlank(sfIntensity)) {
                                    //如果烈度是5度则按照6度来算，如果是11和12度则按照10度来算
                                    if ("5".equals(sfIntensity)) {
                                        sfIntensity = "6度";
                                    } else if ("11".equals(sfIntensity)) {
                                        sfIntensity = "10度";
                                    } else if ("12".equals(sfIntensity)) {
                                        sfIntensity = "10度";
                                    } else {
                                        sfIntensity += "度";
                                    }
                                }
                                //白天 夜晚
                                for (Integer datePeriod : getDayPeriod()) {
                                    List<CasualtiesPECalculation> dayList = new ArrayList<>();
                                    List<CasualtiesPECalculation> nightList = new ArrayList<>();
                                    //破坏程度(轻微破坏~损坏)
                                    for (String destroyDegree : detoryList) {
                                        //totalMh 表示在白天或黑夜 某中破坏状态下的重伤人数
                                        BigDecimal totalMh = BigDecimal.ZERO;
                                        //totalMd 表示在白天或黑夜 某中破坏状态下的死亡人数
                                        BigDecimal totalMd = BigDecimal.ZERO;
                                        //破坏程度与对应的重伤比
                                        BigDecimal rh = getInjureMap().get(destroyDegree);
                                        //破坏程度与对应的死亡比
                                        BigDecimal rd = getDeathMap().get(destroyDegree);
                                        for (int i=0;i<damageList.size();i++) {
                                            String damage =  damageList.get(i);
                                            BigDecimal fVal = valueList.get(i);
                                            //将0.04g	0.09g	0.19g	0.38g	0.75g转换成对应的烈度
                                            String realIntensity = getRealIntensity(damage);
                                            //获取到的函数值
                                            BigDecimal funtionValue = BigDecimal.ZERO;
                                            //易损性结构类型
                                            String structure = getStructure(null, entity, dictMap);
                                            if ("1".equals(risk)) {
                                                //pga数据
                                                fVal = BigDecimal.ONE;
                                                funtionValue = getFunctionValue(structure, mapTable, destroyDegree, realIntensity, sfIntensity,functionMap);
                                                if(funtionValue == null){
                                                    continue;
                                                }
                                            } else if ("0".equals(risk)) {
                                                //烈度数据
                                                String intensity = getRealIntensity(realIntensity);
                                                funtionValue = getIdFuntionValue(structure, sfIntensity, destroyDegree, intensity, ysxMap);
                                            }
                                            //室内人员昼夜在三类结构中的的百分比
                                            List<BigDecimal> ratioByStructureCategory = getRatioByStructureCategory(entity.getUsage1());
                                            //房屋用途在白天和夜晚下人员在室内的百分比
                                            BigDecimal C = ratioByStructureCategory.get(datePeriod);
                                            //三类房屋用途在不同设防情况下的占比面积
                                            BigDecimal sfArea = org.apache.commons.lang3.StringUtils.isBlank(entity.getArea()) ? BigDecimal.ZERO : new BigDecimal(entity.getArea());
                                            //A4（0.01）=S(砖混)*易损性值（0.01、砖混、轻微破坏）
                                            BigDecimal a4 = sfArea.multiply(funtionValue).multiply(fVal);
                                            //Mh(I、0.01)=C*η*A4（0.01）*rh4)   Mh是不同破坏状态下的人员受伤情况
                                            BigDecimal mh = C.multiply(a4).multiply(rh).multiply(η);
                                            BigDecimal md = C.multiply(a4).multiply(rd).multiply(η);
                                            totalMh = totalMh.add(mh).setScale(6, RoundingMode.HALF_DOWN);
                                            totalMd = totalMd.add(md).setScale(6, RoundingMode.HALF_DOWN);
                                        }
                                        //重伤数据
                                        CasualtiesPECalculation injureCalculation = getCasualtiesPECalculation(years, calculationTasks, entity.getProvince(), entity.getCity(), entity.getCounty(), entity.getId(), datePeriod + "", entity.getGeomText(), destroyDegree, totalMh, "rysw1", "");
                                        Integer sort = buildDamageSortMap().get(destroyDegree);
                                        injureCalculation.setSort(sort);
                                        dayList.add(injureCalculation);
                                        //死亡数据
                                        CasualtiesPECalculation deathCalculation = getCasualtiesPECalculation(years, calculationTasks, entity.getProvince(), entity.getCity(), entity.getCounty(), entity.getId(), datePeriod + "", entity.getGeomText(), destroyDegree, totalMd, "rysw2", "");
                                        deathCalculation.setSort(sort);
                                        nightList.add(deathCalculation);
                                    }
                                    //List<CasualtiesPECalculation> sortList1 = dayList.stream().sorted(Comparator.comparing(CasualtiesPECalculation::getSort)).collect(Collectors.toList());
                                    result.addAll(dayList);
                                    //List<CasualtiesPECalculation> sortList2 = nightList.stream().sorted(Comparator.comparing(CasualtiesPECalculation::getSort)).collect(Collectors.toList());
                                    result.addAll(nightList);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (result.size() > 0) {
            //查询抗震能力的计算结果
            //getPtValueAndSave(result, calculationTasks);
            //批量保存
            casualtiesPERepository.batchCalculation(result);
        }
        //更新计算进度
        if (calculationTasks.getSeismicInputMode().equals("3")) {
            calculationTasksRepository.updateFSProgress(taskId, "评估", "经济损失");
        }
        if (calculationTasks.getSeismicInputMode().equals("4")) {
            calculationTasksRepository.updateCYProgress(taskId, "评估", "经济损失");
        }
        boolean bool = hypergraphService.getWorkspaceReload("fxqh_casualties_calculation_pd");
        Long end = System.currentTimeMillis();
        System.out.println("时间消耗:" + (end - start) / 1000);
    }

//    public void calculation(String taskId) throws Exception {
//        casualtiesPERepository.deleteEvaluateResult(taskId);
//        //初始化T年为1
//        String years = "1";
//        Long start = System.currentTimeMillis();
//        //组建数据格式
//        Map<String, Map<String, Table<String, BigDecimal, BigDecimal>>> pgaMap = new HashMap<>();
//        Map<String, Map<String, List<BigDecimal>>> ldMap = new HashMap<>();
//        //获取评估记录信息
//        // ResistEarthquakesPE casualtiesPE = resistEarthquakesPERepository.findById(assessId);
//        CalculationTasks calculationTasks = calculationTasksService.findById(taskId);
//        if ("3".equals(calculationTasks.getSeismicInputMode())) {
//            if (PlatformObjectUtils.isNotEmpty(calculationTasks.getStructuralOccurrenceProgress()) && "0".equals(calculationTasks.getStructuralOccurrenceProgress())) {
//                throw new RuntimeException("请先计算结构破坏-发生概率危险性的确认评估！");
//            }
//        } else if ("4".equals(calculationTasks.getSeismicInputMode())) {
//            if (PlatformObjectUtils.isNotEmpty(calculationTasks.getStructuralGoBeyondProgress()) && "0".equals(calculationTasks.getStructuralGoBeyondProgress())) {
//                throw new RuntimeException("请先计算结构破坏-超越概率危险性的确认评估！");
//            }
//        } else {
//            throw new RuntimeException("参数错误，请联系管理员！");
//        }
//        //房屋基础数据选择方式
//        String houseDataFlag = calculationTasks.getHouseDataFlag();
//        //radio2:0为省市区县1为地图圈选
//        String radio2 = calculationTasks.getRadio2();
//        String geom = "";
//        if ("0".equals(radio2)) {
//            List<PCC> list = pccRepository.queryToponym(taskId);
//            geom = publicOperateService.getUnionGeomByCode(list);
//        } else if ("1".equals(radio2)) {
//            geom = calculationTasks.getCoordinateRange();
//        }
//        //获取人口格网数据
//        List<LinkedHashMap> popoluationList = getPopoluationList(calculationTasks.getPopluationVersion(), null);
//        if (PlatformObjectUtils.isEmpty(popoluationList) || popoluationList.size() == 0) {
//            throw new RuntimeException("计算未完成,人口格网版本为" + calculationTasks.getPopluationVersion() + "下没有人口格网数据");
//        }
//        //破坏程度的集合
//        List<String> detoryList = getDetoryList();
//        List<CasualtiesPECalculation> result = new ArrayList<>();
//        if (org.apache.commons.lang3.StringUtils.isNotBlank(geom)) {
//            //发生概率危险性数据
//            //1：pga,0：烈度
//            String risk = calculationTasks.getLdPga();
//            //Table<String, List<String>, List<BigDecimal>> table = publicOperateService.buildPsHazardDataValue(psHazardDataValueList);
//            //根据版本获取人口格网数据并将人口和extends1进行关联
//            Map<String, BigDecimal> popMap = getPopMap(popoluationList);
//            Table<String, List<String>, List<BigDecimal>> table = null;
//            //使用的是房屋格网数据
//            if ("1".equals(houseDataFlag)) {
//                //超越概率
//                if ("4".equals(calculationTasks.getSeismicInputMode())) {
//                    table = publicOperateService.transition1(geom, calculationTasks.getBeyondProbabilisticVersion(), "0");
//                } else if ("3".equals(calculationTasks.getSeismicInputMode())) {
//                    List<PsHazardDataValue> psHazardDataValueList = publicOperateService.getPsHazardDataValueList(risk, geom);
//                    table = publicOperateService.buildPsHazardDataValue(psHazardDataValueList);
//                }
//                List<DictEntityVo> dictItemByDictId = dictItemService.getDictItemByDictCode("jzwglgwlx");
//                //Map<String, List<PsHazardDataValue>> kiloMap = psHazardDataValueList.stream().collect(Collectors.groupingBy(PsHazardDataValue::getKilometerGridId));
//                //List<String> kilometerGridIds = psHazardDataValueList.stream().map(PsHazardDataValue::getKilometerGridId).distinct().collect(Collectors.toList());
//                if (table != null) {
//                    List<Grid13VO> jggwList1 = calculationTasksRepository.getLdDate(calculationTasks.getId(), "", "");
//                    Set<String> kilometerGridIds = table.rowKeySet();
//                    for (String kilometerGridId : kilometerGridIds) {
//                        String province = "", city = "", county = "";
//                        String geographyId = kilometerGridId;
//                        //获取发生概率危险性的X（im或烈度）数据
//                        List<String> damageList = getDamageXList(table, kilometerGridId);
//                        //13张表数据同属于一个完整格网的白天或夜晚的重伤的数据
//                        Table<String, String, BigDecimal> mhTable = HashBasedTable.create();
//                        //13张表数据同属于一个完整格网的白天或夜晚的死亡的数据
//                        Table<String, String, BigDecimal> mdTable = HashBasedTable.create();
//                        //13张表数据同属于一个完整格网的总面积
//                        BigDecimal totalAreaAll = BigDecimal.ZERO;
//                        BigDecimal popNum = popMap.get(kilometerGridId);
//                        if (popNum == null) {
//                            continue;
//                        }
//                        int flag = 0;
//                        //循环遍历获取13张房屋网格数据
//                        //因为13张表同一条数据的extends1相同，但并不代表着同一个extends1的13条数据的空间数据就完全一样，只是同一个extends1的13条数据的空间数据的中心点相同
//                        //所以geomVal只需要保存一条数据的空间数据即可，用于数据库表字段的保存
//                        String geomVal = "";
//                        for (DictEntityVo vo : dictItemByDictId) {
//                            //获取13张房屋网格数据
//                            //List<Grid13VO> jggwList = get13GridList(kilometerGridId, vo, calculationTasks.getHouseData());
//                            List<Grid13VO> jggwList = new ArrayList<>();
//
//                            jggwList = jggwList1.stream().filter(entity -> entity.getExtends1().equals(kilometerGridId) && entity.getDictionary().equals(vo.getDictItemCode())).collect(Collectors.toList());
//                            if (PlatformObjectUtils.isEmpty(jggwList)) {
//                                continue;
//                            }
//                            //如果房屋网格数据准确的话，一条psHazardDataValue数据根据extends1字段每次只会检索出一条格网数据
//                            Grid13VO obj = jggwList.get(0);
//                            if("".equals(geomVal)){
//                                geomVal = obj.getGeom() ;
//                            }
//                            //结构类型_设防情况,<破坏程度，mr,br>
//                            Map<String, Table<String, BigDecimal, BigDecimal>> mapTable = null;
//                            Map<String, List<BigDecimal>> ysxMap = null;
//                            if ("1".equals(risk)) {
//                                mapTable = handlePageOfYsx(obj.getProvince(), obj.getCity(), obj.getCounty(), pgaMap);
//                            } else if ("0".equals(risk)) {
//                                ysxMap = handleYsx(obj.getProvince(), obj.getCity(), obj.getCounty(), ldMap);
//                                if (PlatformObjectUtils.isEmpty(ysxMap)) {
//                                    continue;
//                                }
//                            }
//                            //根据省市区县查询易损性数据
//                            province = obj.getProvince();
//                            city = obj.getCity();
//                            county = obj.getCounty();
//                            totalAreaAll = totalAreaAll.add(new BigDecimal(obj.getTotalArea()));
//                            //判断网格的房屋用途并返回各自所占的面积  如1-100.00  1表示是第几类房屋用途 100.00表示是该类房屋用途的面积
//                            List<String> houseUsingAreaList = getHouseUsingArea(obj);
//                            //设防烈度
//                            List<String> sfIntensityList = getIntensityList(obj);
//                            //获取房屋格网的设防情况 并返回各自所占的比例
//                            Map<String, BigDecimal> intensitArea = getIntensitArea(obj);
//                            //白天 夜晚
//                            for (Integer datePeriod : getDayPeriod()) {
//                                //破坏程度(轻微破坏~损坏)
//                                for (String destroyDegree : detoryList) {
//                                    int num = 0;
//                                    //totalMh 表示在白天或黑夜 某中破坏状态下的重伤人数
//                                    BigDecimal totalMh = BigDecimal.ZERO;
//                                    //totalMd 表示在白天或黑夜 某中破坏状态下的死亡人数
//                                    BigDecimal totalMd = BigDecimal.ZERO;
//                                    //破坏程度与对应的重伤比
//                                    BigDecimal rh = getInjureMap().get(destroyDegree);
//                                    //破坏程度与对应的死亡比
//                                    BigDecimal rd = getDeathMap().get(destroyDegree);
//                                    //发生概率地震危险性X值(VI或0.01) 如0.01
//                                    for (String damage : damageList) {
//                                        //设防烈度 如未设防
//                                        for (String sfIntensity : sfIntensityList) {
//                                            //不同设防情况面积占比
//                                            BigDecimal ratio = intensitArea.get(sfIntensity);
//                                            //获取到的函数值
//                                            BigDecimal funtionValue = BigDecimal.ZERO;
//                                            //易损性结构类型
//                                            String structure = getStructure(obj, null, null);
//                                            if ("1".equals(risk)) {
//                                                //pga数据
//                                                funtionValue = getFunctionValue(structure, mapTable, destroyDegree, damage, sfIntensity);
//                                            } else if ("0".equals(risk)) {
//                                                //烈度数据
//                                                funtionValue = getIdFuntionValue(structure, sfIntensity, destroyDegree, damage, ysxMap);
//                                            }
//                                            //房屋用途（三类房屋用途）
//                                            for (String houseUsingArea : houseUsingAreaList) {
//                                                //房屋用途编号  （第一类1、第二类2、第三类3）
//                                                String houseUsingIndex = houseUsingArea.split("-")[0];
//                                                //房屋用途对应的面积
//                                                String area = houseUsingArea.split("-")[1];
//                                                //室内人员昼夜在三类结构中的的百分比
//                                                List<BigDecimal> ratioByStructureCategory = getRatioByStructureCategory(houseUsingIndex);
//                                                //房屋用途在白天和夜晚下人员在室内的百分比
//                                                BigDecimal C = ratioByStructureCategory.get(datePeriod);
//                                                //三类房屋用途在不同设防情况下的占比面积
//                                                BigDecimal sfArea = new BigDecimal(area).multiply(ratio.divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
//                                                //A4（0.01）=S(砖混)*易损性值（0.01、砖混、轻微破坏）
//                                                BigDecimal a4 = sfArea.multiply(funtionValue);
//                                                //Mh(I、0.01)=C*η*A4（0.01）*rh4)   Mh是不同破坏状态下的人员受伤情况
//                                                BigDecimal mh = C.multiply(a4).multiply(rh);
//                                                BigDecimal md = C.multiply(a4).multiply(rd);
//                                                totalMh = totalMh.add(mh);
//                                                totalMd = totalMd.add(md);
//                                            }
//                                        }
//                                    }
//                                    BigDecimal mhTatal = mhTable.get(datePeriod , destroyDegree);
//                                    if (mhTatal != null && mhTatal.compareTo(BigDecimal.ZERO) > 0) {
//                                        BigDecimal newResult = totalMh.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mhTatal = mhTatal.add(newResult);
//                                        mhTable.put(datePeriod+"" , destroyDegree, mhTatal);
//                                    } else {
//                                        BigDecimal newResult = totalMh.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mhTable.put(datePeriod + "" , destroyDegree, newResult);
//                                    }
//                                    BigDecimal mdTatal = mdTable.get(datePeriod + "" , destroyDegree);
//                                    if (mdTatal != null && mdTatal.compareTo(BigDecimal.ZERO) > 0) {
//                                        BigDecimal newResult = totalMd.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mdTatal = mdTatal.add(newResult);
//                                        mdTable.put(datePeriod + "" , destroyDegree, mdTatal);
//                                    } else {
//                                        BigDecimal newResult = totalMd.setScale(6, BigDecimal.ROUND_DOWN);
//                                        mdTable.put(datePeriod + "" , destroyDegree, newResult);
//                                    }
//                                }
//                            }
//                            flag = 1;
//                        }
//                        if (flag > 0) {
//                            //η—房屋内人员的密度
//                            BigDecimal η = BigDecimal.ZERO;
//                            if (totalAreaAll.compareTo(BigDecimal.ZERO) > 0) {
//                                η = popNum.divide(totalAreaAll, 6, RoundingMode.HALF_DOWN);
//                            }
//                            //<0/1,<破坏程度，人员重伤数>
//                            Map<String, Map<String, BigDecimal>> injureMap = mhTable.rowMap();
//                            BigDecimal finalη = η;
//                            String finalProvince = province;
//                            String finalCity = city;
//                            String finalCounty = county;
//                            String finalGeographyId = geographyId;
//                            String finalExtends1 = kilometerGridId;
//                            //白天或黑夜下的几种破坏程度的重伤人数
//                            String finalGeomVal = geomVal;
//                            injureMap.forEach((k, v) -> {
//                                //k是白天（1）和黑夜（0）- 空间数据，v是<破坏程度，人员重伤数量>
//                                String k1 = k.split("-")[0];
//                                //空间数据
//                                String k2 = finalGeomVal;
//                                v.forEach((a, b) -> {
//                                    //a是破坏程度 b是重伤数量
//                                    b = b.multiply(finalη);
//                                    CasualtiesPECalculation calculation = getCasualtiesPECalculation(years, calculationTasks, finalProvince, finalCity, finalCounty, finalGeographyId, k1, k2, a, b, "rysw1", finalExtends1);
//                                    Integer sort = buildDamageSortMap().get(a);
//                                    calculation.setSort(sort);
//                                    result.add(calculation);
//                                });
//                            });
//                            //<0/1,<破坏程度，人员重伤数>
//                            Map<String, Map<String, BigDecimal>> deathMap = mdTable.rowMap();
//                            //白天或黑夜下的几种破坏程度的死亡人数
//                            String finalGeomVal1 = geomVal;
//                            deathMap.forEach((k, v) -> {
//                                //k是白天（1）和黑夜（0）- 空间数据，v是<破坏程度，人员重伤数量>
//                                String k1 = k.split("-")[0];
//                                //空间数据
//                                String k2 = finalGeomVal1;
//                                List<CasualtiesPECalculation> tempList = new ArrayList<>();
//                                v.forEach((a, b) -> {
//                                    //a是破坏程度 b是重伤数量
//                                    b = b.multiply(finalη);
//                                    CasualtiesPECalculation calculation = getCasualtiesPECalculation(years, calculationTasks, finalProvince, finalCity, finalCounty, finalGeographyId, k1, k2, a, b, "rysw2", finalExtends1);
//                                    Integer sort = buildDamageSortMap().get(a);
//                                    calculation.setSort(sort);
//                                    tempList.add(calculation);
//                                });
//                                //List<CasualtiesPECalculation> sortedList = tempList.stream().sorted(Comparator.comparing(CasualtiesPECalculation::getSort)).collect(Collectors.toList());
//                                result.addAll(tempList);
//                            });
//                        }
//                    }
//                }
//            } else {
//                //使用的是房屋单体数据数据
//                //查询字典项
//                Map<Object, Object> dictMap = redisTemplate.opsForHash().entries("FXQH:" + FxfzConstants.CACHE_SYS_KEY + "dictItemMapForEvaluate");
//                if (dictMap == null || dictMap.values().size() == 0) {
//                    dictMap = dictItemService.getDictItemMap();
//                }
//                //超越概率危险性
//                if ("4".equals(calculationTasks.getSeismicInputMode())) {
//                    table = publicOperateService.transition1(geom, calculationTasks.getBeyondProbabilisticVersion(), "1");
//                } else if ("3".equals(calculationTasks.getSeismicInputMode())) {
//                    //发生概率危险性
//                    List<PsHazardDataValue> psHazardDataValueList = publicOperateService.getPsHazardDataValueList(risk, geom);
//                    table = publicOperateService.buildPsHazardDataValue2(psHazardDataValueList);
//                }
//                Map<String, BigDecimal> popGridMap = buildGridMap(popoluationList, calculationTasks.getHouseData());
//                if (table != null) {
//                    Set<String> geomList = table.rowKeySet();
//                    //for (PsHazardDataValue psHazardDataValue : psHazardDataValueList) {
//                    for (String geom1 : geomList) {
//                        List<BuildingIndividualEntity> buildingIndividualVOs = publicOperateService.getBuildingIndividualVOs(geom1, calculationTasks.getHouseData());
//                        if (PlatformObjectUtils.isNotEmpty(buildingIndividualVOs) && buildingIndividualVOs.size() > 0) {
//                            //获取发生概率危险性的X（im或烈度）数据
//                            List<String> damageList = getDamageXList(table, geom1);
//                            for (BuildingIndividualEntity entity : buildingIndividualVOs) {
//                                BigDecimal percent = popGridMap.get(entity.getBuildingCode());
//                                if (percent == null) {
//                                    percent = BigDecimal.ZERO;
//                                }
//                                //结构类型_设防情况,<破坏程度，mr,br>
//                                Map<String, Table<String, BigDecimal, BigDecimal>> mapTable = null;
//                                Map<String, List<BigDecimal>> ysxMap = null;
//                                if ("0".equals(risk)) {
//                                    mapTable = handlePageOfYsx(entity.getProvince(), entity.getCity(), entity.getCounty(), pgaMap);
//                                } else if ("1".equals(risk)) {
//                                    ysxMap = handleYsx(entity.getProvince(), entity.getCity(), entity.getCounty(), ldMap);
//                                }
//                                String area = entity.getArea();
//                                BigDecimal η = BigDecimal.ZERO;
//                                if (org.apache.commons.lang3.StringUtils.isNotBlank(area)) {
//                                    //室内人口密度
//                                    η = percent.multiply(new BigDecimal(area));
//                                }
//                                //设防情况
//                                String sfIntensity = entity.getDefenceLevel();
//
//                                if (org.apache.commons.lang3.StringUtils.isNotBlank(sfIntensity)) {
//                                    //如果烈度是5度则按照6度来算，如果是11和12度则按照10度来算
//                                    if ("5".equals(sfIntensity)) {
//                                        sfIntensity = "6度";
//                                    } else if ("11".equals(sfIntensity)) {
//                                        sfIntensity = "10度";
//                                    } else if ("12".equals(sfIntensity)) {
//                                        sfIntensity = "10度";
//                                    } else {
//                                        sfIntensity += "度";
//                                    }
//                                }
//                                //白天 夜晚
//                                for (Integer datePeriod : getDayPeriod()) {
//                                    List<CasualtiesPECalculation> dayList = new ArrayList<>();
//                                    List<CasualtiesPECalculation> nightList = new ArrayList<>();
//                                    //破坏程度(轻微破坏~损坏)
//                                    for (String destroyDegree : detoryList) {
//                                        //totalMh 表示在白天或黑夜 某中破坏状态下的重伤人数
//                                        BigDecimal totalMh = BigDecimal.ZERO;
//                                        //totalMd 表示在白天或黑夜 某中破坏状态下的死亡人数
//                                        BigDecimal totalMd = BigDecimal.ZERO;
//                                        //破坏程度与对应的重伤比
//                                        BigDecimal rh = getInjureMap().get(destroyDegree);
//                                        //破坏程度与对应的死亡比
//                                        BigDecimal rd = getDeathMap().get(destroyDegree);
//                                        //发生概率地震危险性X值(VI或0.01) 如0.01
//                                        for (String damage : damageList) {
//                                            //设防烈度 如未设防
//                                            //获取到的函数值
//                                            BigDecimal funtionValue = BigDecimal.ZERO;
//                                            //易损性结构类型
//                                            String structure = getStructure(null, entity, dictMap);
//                                            if ("0".equals(risk)) {
//                                                //pga数据
//                                                funtionValue = getFunctionValue(structure, mapTable, destroyDegree, damage, sfIntensity);
//                                            } else if ("1".equals(risk)) {
//                                                //烈度数据
//                                                funtionValue = getIdFuntionValue(structure, sfIntensity, destroyDegree, damage, ysxMap);
//                                            }
//                                            //室内人员昼夜在三类结构中的的百分比
//                                            List<BigDecimal> ratioByStructureCategory = getRatioByStructureCategory(entity.getUsage1());
//                                            //房屋用途在白天和夜晚下人员在室内的百分比
//                                            BigDecimal C = ratioByStructureCategory.get(datePeriod);
//                                            //三类房屋用途在不同设防情况下的占比面积
//                                            BigDecimal sfArea = org.apache.commons.lang3.StringUtils.isBlank(entity.getArea()) ? BigDecimal.ZERO : new BigDecimal(entity.getArea());
//                                            //A4（0.01）=S(砖混)*易损性值（0.01、砖混、轻微破坏）
//                                            BigDecimal a4 = sfArea.multiply(funtionValue);
//                                            //Mh(I、0.01)=C*η*A4（0.01）*rh4)   Mh是不同破坏状态下的人员受伤情况
//                                            BigDecimal mh = C.multiply(a4).multiply(rh).multiply(η);
//                                            BigDecimal md = C.multiply(a4).multiply(rd).multiply(η);
//                                            totalMh = totalMh.add(mh).setScale(6, RoundingMode.HALF_DOWN);
//                                            totalMd = totalMd.add(md).setScale(6, RoundingMode.HALF_DOWN);
//                                        }
//                                        //重伤数据
//                                        CasualtiesPECalculation injureCalculation = getCasualtiesPECalculation(years, calculationTasks, entity.getProvince(), entity.getCity(), entity.getCounty(), entity.getId(), datePeriod + "", entity.getGeomText(), destroyDegree, totalMh, "rysw1", "");
//                                        Integer sort = buildDamageSortMap().get(destroyDegree);
//                                        injureCalculation.setSort(sort);
//                                        dayList.add(injureCalculation);
//                                        //死亡数据
//                                        CasualtiesPECalculation deathCalculation = getCasualtiesPECalculation(years, calculationTasks, entity.getProvince(), entity.getCity(), entity.getCounty(), entity.getId(), datePeriod + "", entity.getGeomText(), destroyDegree, totalMd, "rysw2", "");
//                                        deathCalculation.setSort(sort);
//                                        nightList.add(deathCalculation);
//                                    }
//                                    //List<CasualtiesPECalculation> sortList1 = dayList.stream().sorted(Comparator.comparing(CasualtiesPECalculation::getSort)).collect(Collectors.toList());
//                                    result.addAll(dayList);
//                                    //List<CasualtiesPECalculation> sortList2 = nightList.stream().sorted(Comparator.comparing(CasualtiesPECalculation::getSort)).collect(Collectors.toList());
//                                    result.addAll(nightList);
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        if (result.size() > 0) {
//            //查询抗震能力的计算结果
//            getPtValueAndSave(result, calculationTasks);
//        }
//        //更新计算进度
//        if (calculationTasks.getSeismicInputMode().equals("3")) {
//            calculationTasksRepository.updateFSProgress(taskId, "评估", "经济损失");
//        }
//        if (calculationTasks.getSeismicInputMode().equals("4")) {
//            calculationTasksRepository.updateCYProgress(taskId, "评估", "经济损失");
//        }
//        boolean bool = hypergraphService.getWorkspaceReload("fxqh_casualties_calculation_pd");
//        Long end = System.currentTimeMillis();
//        System.out.println("时间消耗:" + (end - start) / 1000);
//    }

    private BigDecimal getIdFuntionValue(String structure, String sfIntensity, String destroyDegree, String damage, Map<String, List<YSXMainTable>> ysxMap) {
        List<YSXMainTable> intensityList = ysxMap.get(structure + "_" + sfIntensity + "_" + damage + "_" + destroyDegree);
        if (PlatformObjectUtils.isNotEmpty(intensityList)) {
            String rate = intensityList.get(0).getRate();
            rate = rate.replace("%","");
            return new BigDecimal(rate).divide(BigDecimal.valueOf(100),8,RoundingMode.HALF_DOWN);
        }else{
            System.out.println("11");
        }
        return BigDecimal.ZERO;
    }
    private BigDecimal getFunctionValue(String structure, Map<String, Map<String, BigDecimal>> mapTable, String destroyDegree, String damage, String sfIntensity,Map<String,BigDecimal> functionMap) {
            Map<String, BigDecimal> ysxTable = mapTable.get(structure + "_" + sfIntensity);
            if(ysxTable==null){
                return null;
            }
            return getValue(ysxTable,destroyDegree);
    }
    private BigDecimal getValue(Map<String, BigDecimal> breakStateMap,String destroyDegree){
        BigDecimal value = null;
        switch (destroyDegree) {
            case "轻微破坏":
                value = breakStateMap.get(destroyDegree).subtract(breakStateMap.get("中等破坏")).setScale(6,RoundingMode.HALF_DOWN);
                break;
            case "中等破坏":
                value = breakStateMap.get(destroyDegree).subtract(breakStateMap.get("严重破坏")).setScale(6,RoundingMode.HALF_DOWN);
                break;
            case "严重破坏":
                value = breakStateMap.get(destroyDegree).subtract(breakStateMap.get("倒塌")).setScale(6,RoundingMode.HALF_DOWN);
                break;
            case "倒塌":
                value = breakStateMap.get(destroyDegree);
                break;
            default:
        }
        return value;
    }
//    private BigDecimal getFunctionValue(String structure, Map<String, Table<String, BigDecimal, BigDecimal>> mapTable, String destroyDegree, String damage, String sfIntensity,Map<String,BigDecimal> functionMap) {
//        BigDecimal funtionValue;
//        Table<String, BigDecimal, BigDecimal> ysxTable = mapTable.get(structure + "_" + sfIntensity);
//        Map<BigDecimal, BigDecimal> rowMap = null;
//        try {
//            rowMap = ysxTable.row(destroyDegree);
//        } catch (NullPointerException e) {
//            e.printStackTrace();
//        }
//        Iterator<Map.Entry<BigDecimal, BigDecimal>> iterator = rowMap.entrySet().iterator();
//        BigDecimal mr = BigDecimal.ZERO;
//        BigDecimal br = BigDecimal.ZERO;
//        while (iterator.hasNext()) {
//            Map.Entry<BigDecimal, BigDecimal> next = iterator.next();
//            mr = next.getKey();
//            br = next.getValue();
//        }
//        if(functionMap.containsKey(structure + "_" + sfIntensity+"_"+mr + "_"+br + "_"+damage)){
//            funtionValue = functionMap.get(structure + "_" + sfIntensity+"_"+mr + "_"+br + "_"+damage);
//        }else{
//            funtionValue = publicOperateService.getFuntionValue(mr + "", br + "", damage);
//            functionMap.put(structure + "_" + sfIntensity+"_"+mr + "_"+br + "_"+damage,funtionValue);
//        }
//        return funtionValue;
//    }

    //table <省市县 <结构类型_设防情况  <破坏程度，mr，br>>>   获取pga易损性曲线信息
    private Map<String, Map<String, BigDecimal>> handlePageOfYsx(String province, String city, String county, Map<String, Map<String, Map<String, BigDecimal>>> map,String ysxVersion,String taskId) throws Exception {
        Map<String, Map<String, BigDecimal>> row = map.get(province + "_" + city + "_" + county);
        //避免重复查询 相同省市县只查询一次
        if (row == null) {
            Map<String, Map<String, BigDecimal>> ysxMap = new HashMap<>();
            if("0".equals(ysxVersion)){
                //0表示国家级数据需要查询承载体的易损性数据
                //获取省市区县的易损性数据
                List<BasicLibraryVo> pgaOfYsx = publicOperateService.getPgaOfYsx(province, city, county);
                for (BasicLibraryVo vo : pgaOfYsx) {
                    String structureType1 = vo.getStructureType();
                    String structureType2 = vo.getStructureType1();
                    String structureType = structureType1 + (PlatformObjectUtils.isNotEmpty(structureType2) ? "-" + structureType2 : "-" + structureType1);
                    Map<String, BigDecimal> table1 = new HashMap<>();
                    List<CurveVo> valueList = vo.getValueList();
                    for (CurveVo stateValue : valueList) {
                        table1.put(stateValue.getBreakState(), stateValue.getFim());
                    }
                    //结构类型_设防烈度,<破坏程度 mr br>
                    ysxMap.put(structureType + "_" + vo.getDefenseSituation(), table1);
                }
                map.put(province + "_" + city + "_" + county, ysxMap);
                return ysxMap;
            }else if("2".equals(ysxVersion)){
                //自定义群体版需要查询本系统的易损性数据
                List<YSXMainTable> ysx = ysxRepository.getYSX2(taskId, province, city, county);
                Map<String, List<YSXMainTable>> ysxMap1 = ysx.stream().collect(Collectors.groupingBy(YSXMainTable::getId));
                ysxMap1.forEach((k, v)->{
                    //k是主表id，v是这个易损性下的多个值
                    String structureType1 = v.get(0).getStructureType1();
                    String structureType2 = v.get(0).getStructureType2();
                    String structureType = structureType1 + (PlatformObjectUtils.isNotEmpty(structureType2) ? "-" + structureType2 : "-" +structureType1);
                    Map<String, BigDecimal> table1 = new HashMap<>();
                    List<CurveVo> valueList = PublicOperateService.turningCurve1(v);
                    for (CurveVo stateValue : valueList) {
                        //破坏程度 value
                        table1.put(stateValue.getBreakState(), stateValue.getFim());
                    }
                    //结构类型_设防烈度,<破坏程度 mr br>
                    ysxMap.put(structureType + "_" + v.get(0).getFortify(), table1);
                });
                map.put(province + "_" + city + "_" + county, ysxMap);
                return ysxMap;
            }
        }
        return row;
    }

    //获取易损性矩阵信息
    private  Map<String, List<YSXMainTable>> handleYsx1(String province, String city, String county, Map<String, Map<String,List<YSXMainTable>>> map,String taskId) throws Exception {
        Map<String, List<YSXMainTable>> ysxMap = map.get(province + "_" + city + "_" + county);
        //避免重复查询，相同省市县只查询一次
        if (ysxMap == null) {
            //根据省市区查询易损性矩阵信息
            List<YSXMainTable> ysxEntityList = ysxRepository.getYSX2(taskId,province, city, county);
            if (PlatformObjectUtils.isNotEmpty(ysxEntityList)) {
                //collect的key是建筑物结构类型+设防烈度度+地震烈度+破坏程度   value是建筑物结构类型+设防雷度+地震烈度+破坏程度下的易损性的数值
                ysxMap = ysxEntityList.stream().collect(Collectors.groupingBy(ysx -> {
                    return ysx.getStructureType1() +"-"+(PlatformObjectUtils.isNotEmpty(ysx.getStructureType2())?ysx.getStructureType2():ysx.getStructureType1() )+ "_" + ysx.getFortify() + "_" +ysx.getIntensity()+ "_" + ysx.getDamage();
                }));
                map.put(province + "_" + city + "_" + county, ysxMap);
                return ysxMap;
            }
            throw new RuntimeException("计算未完成，无法获取"+province+""+city+""+county+"的易损性数据");
        }
        return ysxMap;
    }
    //获取易损性矩阵信息
    private Map<String, List<BigDecimal>> handleYsx(String province, String city, String county, Map<String, Map<String, List<BigDecimal>>> map) throws Exception {
        Map<String, List<BigDecimal>> ysxMap = map.get(province + "_" + city + "_" + county);
        //避免重复查询，相同省市县只查询一次
        if (ysxMap == null) {
            Map<String, List<BigDecimal>> ysxMap1 = new HashMap<>();
            //根据省市区查询易损性矩阵信息
            List<YSXEntity> ysxEntityList = ysxRepository.getYSX(province, city, county);
            if (PlatformObjectUtils.isNotEmpty(ysxEntityList)) {
                //collect的key是建筑物结构类型+设防雷度+破坏程度   value是建筑物结构类型+设防雷度+破坏程度下的6~10地震烈度的易损性的数值
                Map<String, List<YSXEntity>> collect = ysxEntityList.stream().collect(Collectors.groupingBy(ysx -> {
                    return ysx.getStructure_type() + "_" + ysx.getFortify() + "_" + ysx.getDamage_degree();
                }));
                collect.forEach((k, v) -> {
                    YSXEntity ysxEntity = v.get(0);
                    List<BigDecimal> intensitySyxValueList = new ArrayList<>(10);
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity6()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity7()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity8()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity9()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                    intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity10()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                    ysxMap1.put(k, intensitySyxValueList);
                });
                map.put(province + "_" + city + "_" + county, ysxMap1);
                return ysxMap1;
            }
        }
        return ysxMap;
    }

    //求房屋单体房屋内人员的密度过程的中间结果-》一个网格中的人口/网格中所有单体的面积
    private Map<String, BigDecimal> buildGridMap(List<LinkedHashMap> popoluationList, String version) {
        Map<String, BigDecimal> popMap = new HashMap<>();
        //室内人员密度  一个网格中的人口/网格中所有单体的面积）*当前单体的面积
        for (LinkedHashMap linkedHashMap : popoluationList) {
            String popGeom = linkedHashMap.get("geom").toString();
            //获取人口格网中所有的房屋单体
            List<PopulationBuildingIndividualVO> vos = buildingIndividualRepository.getAllWithGeomAndArea(popGeom, version, "", "", "");
            Object obj = linkedHashMap.get("tzl3");
            BigDecimal divide = BigDecimal.ZERO;
            if (PlatformObjectUtils.isNotEmpty(obj)) {
                //人口数量
                BigDecimal totalPopulation = new BigDecimal(obj.toString());
                if (PlatformObjectUtils.isNotEmpty(vos) && vos.size() > 0) {
                    BigDecimal totalArea = vos.stream().filter(populationBuildingIndividualVO -> PlatformObjectUtils.isNotEmpty(populationBuildingIndividualVO.getArea()))
                            .map(PopulationBuildingIndividualVO::getArea)
                            // 使用reduce()聚合函数,实现累加器
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    divide = totalPopulation.divide(totalArea, 6, RoundingMode.HALF_DOWN);
                }
            }
            for (PopulationBuildingIndividualVO vo : vos) {
                popMap.put(vo.getBuildingCode(), divide);
            }
        }
        return popMap;
    }

    private Map<String, String> getIntensityMap() {
        Map<String, String> map = new HashMap<>();
        map.put("pgcd2", "轻微破坏");
        map.put("pgcd3", "中等破坏");
        map.put("pgcd4", "严重破坏");
        map.put("pgcd5", "倒塌");
        return map;
    }

    //获取概率值并批量保存
    private void getPtValueAndSave(List<CasualtiesPECalculation> result, CalculationTasks calculationTasks) {
        List<ResistEarthquakesPECalculation> resistListList = resistEarthquakesPERepository.queryCalculation1(calculationTasks.getId());
        if (PlatformObjectUtils.isNotEmpty(resistListList) && resistListList.size() > 0) {
            //Map<String, ResistEarthquakesPECalculation> idMap = resistListList.stream().collect(Collectors.toMap(ResistEarthquakesPECalculation::getGeographyId+"-"+, Function.identity()));
            Map<String, ResistEarthquakesPECalculation> idMap = new HashMap<>();
            if (PlatformObjectUtils.isNotEmpty(resistListList) && resistListList.size() > 0) {
                for (ResistEarthquakesPECalculation calculation : resistListList) {
                    idMap.put(calculation.getGeographyId() + "-" + (getIntensityMap().get(calculation.getDamageDegree())), calculation);
                }
            }

            for (String years : calculationTasks.getYear().split(",")) {
                for (CasualtiesPECalculation casualtiesPECalculation : result) {
                    ResistEarthquakesPECalculation calculation = idMap.get(casualtiesPECalculation.getExtends1() + "-" + casualtiesPECalculation.getExtreme());
                    //之前生成的UUID 都是T年都是重复的，这里重新生成。
                    casualtiesPECalculation.setId(UUIDGenerator.getUUID());
                    //T年
                    casualtiesPECalculation.setYears(years);
                    //概率P(1)计算值
                    casualtiesPECalculation.setCalculatedValuePt(calculation.getCalculatedValueP1().toString());
                    //概率P(1)修正值
                    casualtiesPECalculation.setCorrectionValuePt(calculation.getCorrectionValueP1().toString());
                    BigDecimal multiply = calculation.getCorrectionValueP1().multiply(new BigDecimal(years));
                    //概率值pt
                    casualtiesPECalculation.setChancePt(multiply.toString());


                    //期望值（临时结果）
                    BigDecimal tempResult = multiply.multiply(casualtiesPECalculation.getCorrectionValue()).setScale(6, BigDecimal.ROUND_DOWN);
                    //临时期望值
                    casualtiesPECalculation.setExpectValue(tempResult);
                }
                //批量保存
                casualtiesPERepository.batchCalculation(result);
            }
        }
    }
    //保存实体数据
    private CasualtiesPECalculation getCasualtiesPECalculation(String years, CalculationTasks calculationTasks
            , String finalProvince, String finalCity, String finalCounty, String finalGeographyId, String time, String geom
            , String destory, BigDecimal personNum, String type, String extends1) {
        CasualtiesPECalculation casualtiesPECalculation = new CasualtiesPECalculation();
        //主键id
        casualtiesPECalculation.setId(UUIDGenerator.getUUID());
        //评估记录id
        casualtiesPECalculation.setAssessId(calculationTasks.getId());
        //评估记录编号
        casualtiesPECalculation.setAssessCode(calculationTasks.getAssessCode());
        //省
        casualtiesPECalculation.setProvinceName(finalProvince);
        //市
        casualtiesPECalculation.setCityName(finalCity);
        //区县
        casualtiesPECalculation.setCountyName(finalCounty);
        //地理id(虚拟ID) 或 房屋单体数据ID
        casualtiesPECalculation.setGeographyId(finalGeographyId);
        //人员伤亡(死亡2重伤1)
        casualtiesPECalculation.setCasualties(type);
        //时间段(白天1晚上0)
        switch (time){
            case "0":
                time = "sjd2";
                break;
            case "1":
                time = "sjd1";
                break;
        }
        casualtiesPECalculation.setTime(time + "");
        //计算值(人)
        casualtiesPECalculation.setCalculatedValue(personNum);
        //修改值(人)
        casualtiesPECalculation.setCorrectionValue(personNum);
        casualtiesPECalculation.setExpectValue(personNum);
        //经纬度范围
        casualtiesPECalculation.setCoordinateRange("");
        //创建人
        casualtiesPECalculation.setCreateUser(PlatformSessionContext.getUserID());
        //创建时间
        casualtiesPECalculation.setCreateTime(new Date());
        //T年
        casualtiesPECalculation.setYears(years);
        //极限破坏(轻微,中等,严重,倒塌)
        casualtiesPECalculation.setExtreme(destory);
        //删除标志0正常1删除
        casualtiesPECalculation.setDelFlag("0");
        casualtiesPECalculation.setExtends1(org.apache.commons.lang3.StringUtils.isNotBlank(extends1) ? extends1 : "");
        casualtiesPECalculation.setRisk(calculationTasks.getLdPga());
        casualtiesPECalculation.setSeismicInputMode(calculationTasks.getSeismicInputMode());
        casualtiesPECalculation.setGeom(geom);
//        if("0".equals(calculationTasks.getRisk()) || "1".equals(calculationTasks.getRisk())){
//            casualtiesPECalculation.setSeismicInputMode("0");
//        }else if("2".equals(calculationTasks.getRisk()) || "3".equals(calculationTasks.getRisk())){
//            casualtiesPECalculation.setSeismicInputMode("1");
//        }
        casualtiesPECalculation.setHouseDataFlag(calculationTasks.getHouseDataFlag());
        return casualtiesPECalculation;
    }

    private List<LinkedHashMap> getPopoluationList(String populationVersion, PCC pcc) throws BizException {
        JcsjDataViewParam jcsjDataViewParam = new JcsjDataViewParam();
        jcsjDataViewParam.setVersionCode(populationVersion);
        if (pcc != null) {
            jcsjDataViewParam.setProvince(pcc.getPpName());
            jcsjDataViewParam.setCity(pcc.getCityName());
            jcsjDataViewParam.setCounty(pcc.getName());
        }
        JcsjDataViewVo data = populationService.queryDataView(jcsjDataViewParam).getData();
        if (data == null || PlatformObjectUtils.isEmpty(data.getData())) {
            return null;
        }
        return (List<LinkedHashMap>) data.getData();
    }

    private List<Grid13VO> get13GridList(String kilometerGridId, DictEntityVo vo, String versionCode) throws StrategyFactoryException {
        QueryByVersionParam queryByVersionParam = new QueryByVersionParam();
        queryByVersionParam.setTypeCode(vo.getDictItemCode());
        queryByVersionParam.setExtends1(kilometerGridId);
        queryByVersionParam.setVersionCode(versionCode);
        //jggwList是13张表数据其中的一张数据
        return fxqhBuildingGridDataVersionService.queryYwData(queryByVersionParam);
    }

    //获取发生概率危险性的IM或烈度数据
    private List<String> getDamageXList(Map<List<String>, List<BigDecimal>> row ) {
        ArrayList<List<String>> keyList = new ArrayList<>(row.keySet());
        return keyList.get(0);
    }
    //获取发生概率危险性的Y值
    private List<BigDecimal> getDamageValList(Map<List<String>, List<BigDecimal>> row ) {
        ArrayList<List<BigDecimal>> valList = new ArrayList<>(row.values());
        return valList.get(0);
    }
//    //烈度易损性值（VI、砖混、轻微破坏）
//    private BigDecimal getIdFuntionValue(Grid13VO obj, String sfIntensity, String destroyDegree, String damage,BuildingIndividualEntity entity , Map<Object, Object> map,Map<String,Map<String, List<BigDecimal>>> disrictYsxMap) throws BizException {
//        //易损性设防结构类型
//        //易损性设防结构类型
//        String mapKey = "";
//        String province ="",city="",county="";
//        if(obj!=null){
//            mapKey = getRelativeYsxStruncture(obj);
//            province = obj.getProvince();
//            city = obj.getCity();
//            county = obj.getCounty();
//        }else if(entity!=null){
//            String structureType1 = PlatformObjectUtils.isEmpty(map.get(entity.getStructureType1()))?"":map.get(entity.getStructureType1()).toString();
//            String structureType2 = PlatformObjectUtils.isEmpty(map.get(entity.getStructureType2()))?"":map.get(entity.getStructureType2()).toString();
//            mapKey = structureType1 + (PlatformObjectUtils.isNotEmpty(structureType2)?"-"+structureType2:"");
//            province = entity.getProvince();
//            city = entity.getCity();
//            county = entity.getCounty();
//        }
//        Integer index = buildIntensityRelation().get(damage);
//        Map<String, List<BigDecimal>> ysxMap = disrictYsxMap.get(province+"-"+city+"-"+county);
//        if(PlatformObjectUtils.isEmpty(ysxMap)){
//            ysxMap = publicOperateService.getYsxMap(province, city, county, disrictYsxMap);
//        }
//        List<BigDecimal> intensityList = ysxMap.get(mapKey + "_" + sfIntensity + "_" + destroyDegree);
//        return intensityList.get(index);
//    }

    private Map<String, Integer> buildIntensityRelation() {
        Map<String, Integer> map = new HashMap<>();
        map.put("Ⅴ", 0);
        map.put("Ⅵ", 0);
        map.put("Ⅶ", 1);
        map.put("Ⅷ", 2);
        map.put("Ⅸ", 3);
        map.put("Ⅹ", 4);
        map.put("Ⅺ", 4);
        map.put("Ⅻ", 4);
        return map;
    }

    //根据房屋网格或房屋单体获取对应的结构类型
    private String getStructure(Grid13VO obj, BuildingIndividualEntity entity, Map<Object, Object> map) {
        //易损性设防结构类型
        String mapKey = "";
        if (obj != null) {
            mapKey = getRelativeYsxStruncture(obj);
            if(!mapKey.contains("-")){
                mapKey = (mapKey+"-"+mapKey);
            }
        } else if (entity != null) {
            String structureType1 = PlatformObjectUtils.isEmpty(map.get(entity.getStructureType1())) ? "" : map.get(entity.getStructureType1()).toString();
            String structureType2 = PlatformObjectUtils.isEmpty(map.get(entity.getStructureType2())) ? structureType1 : map.get(entity.getStructureType2()).toString();
            mapKey = structureType1 + (PlatformObjectUtils.isNotEmpty(structureType2) ? "-" + structureType2 : "");
        }
        return mapKey;
    }

//    //获取易损性函数值
//    private BigDecimal getFuntionValue(Grid13VO obj, String sfIntensity, String destroyDegree, String im, BuildingIndividualEntity entity, Map<Object, Object> map, Map<String, Map<String, BasicLibraryVo>> disrictMap) throws BizException {
//        //易损性设防结构类型
//        String mapKey = "";
//        String province = "", city = "", county = "";
//        if (obj != null) {
//            mapKey = getRelativeYsxStruncture(obj);
//            province = obj.getProvince();
//            city = obj.getCity();
//            county = obj.getCounty();
//        } else if (entity != null) {
//            String structureType1 = PlatformObjectUtils.isEmpty(map.get(entity.getStructureType1())) ? "" : map.get(entity.getStructureType1()).toString();
//            String structureType2 = PlatformObjectUtils.isEmpty(map.get(entity.getStructureType2())) ? "" : map.get(entity.getStructureType2()).toString();
//            mapKey = structureType1 + (PlatformObjectUtils.isNotEmpty(structureType2) ? "-" + structureType2 : "");
//            province = entity.getProvince();
//            city = entity.getCity();
//            county = entity.getCounty();
//        }
//        //basicMapde key是易损性设防结构类型-设防情况
//        Map<String, BasicLibraryVo> basicMap = disrictMap.get(province + "-" + city + "-" + county);
//        if (PlatformObjectUtils.isEmpty(basicMap)) {
//            basicMap = publicOperateService.getBasicMap(province, city, county, disrictMap);
//        }
//        BasicLibraryVo basicLibraryVo = basicMap.get(mapKey + "-" + sfIntensity);
//        if (basicLibraryVo == null) {
//            //todo 要改
//            return BigDecimal.valueOf(0.2);
//            //throw new RuntimeException("计算失败，请先维护"+mapKey+"下的"+sfIntensity+"的易损性曲线信息");
//        }
//        List<BasicLibraryVo.stateValue> vList = basicLibraryVo.getValueList();
//        Map<String, BasicLibraryVo.stateValue> destroyMap = vList.stream().collect(Collectors.toMap(BasicLibraryVo.stateValue::getDestructiveState, Function.identity()));
//        BasicLibraryVo.stateValue stateValue = destroyMap.get(destroyDegree);
//        if (PlatformObjectUtils.isEmpty(stateValue.getMr())) {
//            //todo 要修改
//            stateValue.setMr(BigDecimal.valueOf(0.1));
//        }
//        //易损性值
//        return publicOperateService.getFuntionValue(stateValue.getMr() + "", stateValue.getBr() + "", im);
//    }

    private List<Integer> getDayPeriod() {
        //0 夜间  1：白天
        return Arrays.asList(0, 1);
    }

    //室内人员昼夜在三类结构中的的百分比
    private List<BigDecimal> getRatioByStructureCategory(String houseUsing) {
        List<BigDecimal> list = new ArrayList();
        if ("1".equals(houseUsing)) {
            list = Arrays.asList(BigDecimal.valueOf(0.925), BigDecimal.valueOf(0.225));
        } else if ("2".equals(houseUsing)) {
            list = Arrays.asList(BigDecimal.valueOf(0.035), BigDecimal.valueOf(0.825));
        } else if ("3".equals(houseUsing)) {
            list = Arrays.asList(BigDecimal.valueOf(0.55), BigDecimal.valueOf(0.025));
        }
        return list;
    }

    //判断网格的房屋用途并返回各自所占的面积
    private List<String> getHouseUsingArea(Grid13VO obj,List<StructureHouseUsingPercent> percentList) {
        List<String> list = new ArrayList<>(5);
        //网格房屋总面积
        BigDecimal totalArea = BigDecimal.valueOf(obj.getTotalArea());
        //住宅房屋面积（第Ⅰ类）
        BigDecimal residence = (obj.getResidence() == 0.0 ? BigDecimal.ZERO : (BigDecimal.valueOf(obj.getResidence()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN)));
        //办公房屋面积（第Ⅱ类）
        BigDecimal office = (obj.getOffice() == 0.0 ? BigDecimal.ZERO : (BigDecimal.valueOf(obj.getOffice()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN)));
        //商业房屋面积（第Ⅲ类）
        BigDecimal business = (obj.getBusiness() == 0.0 ? BigDecimal.ZERO : (BigDecimal.valueOf(obj.getBusiness()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN)));
        //医疗教育面积（第Ⅲ类）
        BigDecimal medic = (obj.getMedic() == 0.0 ? BigDecimal.ZERO : (BigDecimal.valueOf(obj.getMedic()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN)));
        //其他房屋面积（第Ⅲ类）
        BigDecimal other = (obj.getOther() == 0.0 ? BigDecimal.ZERO : (BigDecimal.valueOf(obj.getOther()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN)));
        //如果有面积，但房屋用途占比都是空或都是0 则使用默认占比
        if (residence.compareTo(BigDecimal.ZERO) == 0 && office.compareTo(BigDecimal.ZERO) == 0 && business.compareTo(BigDecimal.ZERO) == 0
                && medic.compareTo(BigDecimal.ZERO) == 0 && other.compareTo(BigDecimal.ZERO) == 0) {

            //格网面积有但是各个房屋用途均为0需要使用数据库中存储的各房屋用途备用比例
            Map<String, List<StructureHouseUsingPercent>> collect = percentList.stream().collect(Collectors.groupingBy(StructureHouseUsingPercent::getStructure));
            StructureHouseUsingPercent structureHouseUsingPercent = collect.get(obj.getStructureType()).get(0);
            residence = structureHouseUsingPercent.getResidence();
            office = structureHouseUsingPercent.getOffice();
            business = structureHouseUsingPercent.getBusiness();
            medic = structureHouseUsingPercent.getMedic();
            other = structureHouseUsingPercent.getOther();
        }
        BigDecimal residenceArea = residence.multiply(totalArea);
        list.add("1" + "-" + residenceArea);
        BigDecimal officeArea = office.multiply(totalArea);
        list.add("2" + "-" + officeArea);
        BigDecimal businessArea = business.multiply(totalArea);
        list.add("3" + "-" + businessArea);
        BigDecimal medicArea = medic.multiply(totalArea);
        list.add("3" + "-" + medicArea);
        BigDecimal otherArea = other.multiply(totalArea);
        list.add("3" + "-" + otherArea);
        return list;
    }

    //构建不同破坏程度的死亡比
    private Map<String, BigDecimal> getDeathMap() {
        Map<String, BigDecimal> map = new HashMap<>();
        map.put("轻微破坏", BigDecimal.ZERO);
        map.put("中等破坏", BigDecimal.valueOf(0.00001));
        map.put("严重破坏", BigDecimal.valueOf(0.001));
        map.put("倒塌", BigDecimal.ONE.divide(BigDecimal.valueOf(60), 6, RoundingMode.HALF_DOWN));
        return map;
    }

    //构建不同破坏程度的重伤比
    private Map<String, BigDecimal> getInjureMap() {
        Map<String, BigDecimal> map = new HashMap<>();
        map.put("轻微破坏", BigDecimal.valueOf(0.00001));
        map.put("中等破坏", BigDecimal.valueOf(0.0001));
        map.put("严重破坏", BigDecimal.valueOf(0.005));
        map.put("倒塌", BigDecimal.ONE.divide(BigDecimal.valueOf(15), 6, RoundingMode.HALF_DOWN));
        return map;
    }

    private void handleGrid13(List<Grid13VO> vos) {
        Map<String, Map<String, Table<String, String, List<BigDecimal>>>> ysxMap = new HashMap<>();
        //map中的key是相同的extents1，value是同一个房屋网格的所有的结构类型的的数据
        Map<String, List<Grid13VO>> map = vos.stream().collect(Collectors.groupingBy(Grid13VO::getExtends1));
        map.forEach((k, v) -> {
            for (Grid13VO obj : v) {
                //获取省市区县
                String province = obj.getProvince();
                String city = obj.getCity();
                String county = obj.getCounty();
                //根据省市区县获取易损性数据 <结构类型，<设防情况,破坏程度，烈度值集合>>
                Map<String, Table<String, String, List<BigDecimal>>> ysxTable = null;
                if (ysxMap.containsKey(province + "-" + city + "-" + county)) {
                    ysxTable = ysxMap.get(province + "-" + city + "-" + county);
                } else {
                    ysxTable = getAndReturnYsx(province, city, county);
                    ysxMap.put(province + "-" + city + "-" + county, ysxTable);
                }
                //每种结构所具备的设防烈度
                List<String> sfIntensityList = getIntensityList(obj);
                //根据格网的建筑物结构类型获取对应的易损性结构类型
                String relativeYsxStruncture = getRelativeYsxStruncture(obj);
                //table <设防烈度,破坏程度,烈度对应的易损性的值的集合>
                Table<String, String, List<BigDecimal>> table = ysxTable.get(relativeYsxStruncture);
                if (sfIntensityList.size() > 0) {
                    for (String damageDegree : getDetoryList()) {
                        for (String sfIntensity : sfIntensityList) {
                            //13种结构类型在不同设防烈度下的比例
                            BigDecimal ratio = getIntensitArea(obj).get(sfIntensity).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN);
                            //13种结构类型在不同设防烈度下的面积
                            BigDecimal sfArea = (PlatformObjectUtils.isNotEmpty(obj.getTotalArea()) ? BigDecimal.valueOf(obj.getTotalArea()) : BigDecimal.ZERO).multiply(ratio);
                            List<BigDecimal> intensitySyxValueList = table.get(sfIntensity, damageDegree);
                            for (BigDecimal intensitySyxValue : intensitySyxValueList) {
                                //易损性面积
                                sfArea.multiply(intensitySyxValue);
                            }
                            //结构类型下指定设防烈度
                            //List<BuildingVulnerability> buildingVulnerabilities = sfIntensityMap.get(sfIntensity);
                        }
                    }

                }
            }
        });
    }

    /**
     * 破坏程度的集合基本完好不参与计算
     */
    private List<String> getDetoryList() {
        //todo
        return Arrays.asList("轻微破坏", "中等破坏", "严重破坏", "倒塌");
    }

    /**
     * 获取建筑物单元格所拥有的设防烈度   设防烈度都没有按未设防100%计算
     */
    private List<String> getIntensityList(Grid13VO obj) {
        List<String> intensityList = new ArrayList<>();
        if (obj.getSfIntensity() > 0) {
            intensityList.add("未设防");
        }
        if (obj.getSfIntensity6() > 0) {
            intensityList.add("6度");
        }
        if (obj.getSfIntensity7() > 0) {
            intensityList.add("7度");
        }
        if (obj.getSfIntensity8() > 0) {
            intensityList.add("8度");
        }
        if (obj.getSfIntensity9() > 0) {
            intensityList.add("9度");
        }
        //实际数据中有的数据，现设防程度占比全是0时，按未设防值100%计算。
        if (intensityList.size() == 0) {
            intensityList.add("未设防");
        }
        return intensityList;
    }

    private Map<String, BigDecimal> getIntensitArea(Grid13VO obj) {
        Map<String, BigDecimal> map = new HashMap<>();
        //实际数据中有的数据，现设防程度占比全是0时，按未设防值100%计算。
        if ((obj.getSfIntensity() == null || obj.getSfIntensity() == 0) && (obj.getSfIntensity6() == null || obj.getSfIntensity6() == 0) &&
                (obj.getSfIntensity7() == null || obj.getSfIntensity7() == 0) && (obj.getSfIntensity8() == null || obj.getSfIntensity8() == 0) &&
                (obj.getSfIntensity9() == null || obj.getSfIntensity9() == 0)) {
            map.put("未设防", BigDecimal.valueOf(100));
        } else {
            map.put("未设防", obj.getSfIntensity() == null || obj.getSfIntensity() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(obj.getSfIntensity()));
            map.put("6度", (obj.getSfIntensity6() == null || obj.getSfIntensity6() == 0) ? BigDecimal.ZERO : BigDecimal.valueOf(obj.getSfIntensity6()));
            map.put("7度", obj.getSfIntensity7() == null || obj.getSfIntensity7() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(obj.getSfIntensity7()));
            map.put("8度", obj.getSfIntensity8() == null || obj.getSfIntensity8() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(obj.getSfIntensity8()));
            map.put("9度", obj.getSfIntensity9() == null || obj.getSfIntensity9() == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(obj.getSfIntensity9()));
        }

        return map;
    }

    private Table buildStructureTable() {
        Table<String, String, String> ysxTable = HashBasedTable.create();
        ysxTable.put("城镇砌体结构", "城镇砌体结构", "砌体结构-砖混结构");
        ysxTable.put("城镇钢混结构", "19", "剪力墙结构");
        ysxTable.put("城镇钢结构", "城镇钢结构", "钢结构");
        ysxTable.put("城镇木结构", "城镇木结构", "木结构");
        ysxTable.put("城镇其他结构", "城镇其他结构", "其他");
        ysxTable.put("农村砌体结构", "农村砌体结构", "砌体结构-砖混结构");
        ysxTable.put("农村土木（石木）结构", "农村土木（石木）结构", "土木结构");
        ysxTable.put("农村底部框架结构", "农村底部框架结构", "砌体结构-砖混结构");
        ysxTable.put("农村木（竹）结构", "农村木（竹）结构", "木结构");
        ysxTable.put("农村混杂结构", "农村混杂结构", "其他");
        ysxTable.put("农村钢混结构", "农村钢混结构", "钢筋混凝土结构-框架结构");
        ysxTable.put("农村钢结构", "农村钢结构", "钢结构");
        ysxTable.put("农村其他结构", "农村其他结构", "其他");
        ysxTable.put("城镇钢混结构", "8", "钢筋混凝土结构-框架结构");
        ysxTable.put("城镇钢混结构", "18", "钢筋混凝土结构-框架-剪力墙结构");
        return ysxTable;
    }

    private String getRelativeYsxStruncture(Grid13VO obj) {
        String mapKey = "";
        //获取对应易损性结构类型
        if (!"城镇钢混结构".equals(obj.getStructureType())) {
            mapKey = (String) buildStructureTable().get(obj.getStructureType(), obj.getStructureType());
        } else {
            //城镇钢混结构需要根据建筑的楼层确定易损性结构类型
            if ((obj.getF1() + obj.getF2F3() + obj.getF4F6() + obj.getF7F10() + obj.getF11F16() + obj.getF17F30() + obj.getF31()) == 0) {
                //实际数据中有的数据层数占比全是0，无层数百分比，结构类型对应时，城镇钢混结构对应到钢筋混凝土结构-框架结构
                mapKey = (String) buildStructureTable().get(obj.getStructureType(), "8");
            } else {
                if (obj.getF31() > 0 || obj.getF17F30() > 0) {
                    mapKey = (String) buildStructureTable().get(obj.getStructureType(), "19");
                } else if (obj.getF7F10() > 0 || obj.getF11F16() > 0) {
                    mapKey = (String) buildStructureTable().get(obj.getStructureType(), "18");
                } else {
                    mapKey = (String) buildStructureTable().get(obj.getStructureType(), "8");
                }
            }
            if ("剪力墙结构".equals(mapKey)) {
                mapKey = "钢筋混凝土结构-" + mapKey;
            }
        }
        return mapKey;
    }

    //根据省市县查询易损性并处理结果
    private Map<String, Table<String, String, List<BigDecimal>>> getAndReturnYsx(String province, String city, String county) {
        Map<String, Table<String, String, List<BigDecimal>>> map = new HashMap<>();
        //查询县的易损性数据
        List<YSXEntity> ysxEntityList = ysxRepository.getYSX(province, city, county);
        if (ysxEntityList == null || ysxEntityList.size() == 0) {
            throw new RuntimeException("评估失败,请维护" + province + "-" + city + "-" + county + "的易损性数据");
        }
        // BiMap sfIntensityMap = BiMap
        if (PlatformObjectUtils.isNotEmpty(ysxEntityList)) {
            //collect的key是建筑物结构类型+设防雷度+破坏程度   value是建筑物结构类型+设防雷度+破坏程度下的6~10地震烈度的易损性的数值
            Map<String, List<YSXEntity>> collect = ysxEntityList.stream().collect(Collectors.groupingBy(ysx -> {
                return ysx.getStructure_type() + "-" + ysx.getFortify() + "-" + ysx.getDamage_degree();
            }));
            collect.forEach((k, v) -> {
                YSXEntity ysxEntity = v.get(0);
                List<BigDecimal> intensitySyxValueList = new ArrayList<>(10);
                intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity6()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity7()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity8()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity9()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                intensitySyxValueList.add(BigDecimal.valueOf(ysxEntity.getIntensity10()).divide(BigDecimal.valueOf(100), 6, RoundingMode.HALF_DOWN));
                Table<String, String, List<BigDecimal>> ysxTable = HashBasedTable.create();
                ysxTable.put(k.split("-")[1], k.split("-")[2], intensitySyxValueList);
                map.put(k.split("-")[0], ysxTable);
            });
        }
        return map;
    }

    //根据评估区域选定方式获取对应数据的空间数据
    private String getGeomByRadio2(ResistEarthquakesPE calculationTasks) throws Exception {
        String geom = "";
        //评估区域选定方式 1:按省市区县 此时list有值，2：coordinateRange有值
        if ("1".equals(calculationTasks.getRadio2())) {
            List<PCC> list = calculationTasks.getList();
            geom = publicOperateService.getUnionGeomByCode(list);
        } else {
            geom = calculationTasks.getCoordinateRange();
        }
        return geom;
    }

    //导入
    @Override
    @Transactional(rollbackFor=Exception.class)
    public String reportImport(InputStream inputStream, String type, String id, String years, String code) {
        Workbook workbook = null;
        try {
            workbook = WorkbookFactory.create(inputStream);

            Map<String, Object> map = getList(workbook, type, id, years, code);
            Object o = map.get("message");
            if (o != null) {
                return String.valueOf(o);
            } else {
                List<CasualtiesPECalculation> list = (List<CasualtiesPECalculation>) map.get("list");
                casualtiesPERepository.batchCalculation(list);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "成功";
    }

    public static int USE_SXSSF_LIMIT = 100000;

    //导出
    @Override
    public void exportData(HttpServletResponse response, CasualtiesPECalculationParam param) {
        try {
            //查询省市县
            List<CasualtiesPCCPEVO> list = casualtiesPERepository.getListPCC(param);
            Workbook workbook = (Workbook) (list.size() < USE_SXSSF_LIMIT ? new XSSFWorkbook() : new SXSSFWorkbook());
            // 全局样式设置
            CellStyle allStyle = workbook.createCellStyle();
            allStyle.setFillPattern(FillPatternType.NO_FILL); // 背景
            allStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());// 填充白色
            allStyle.setBorderBottom(BorderStyle.THIN); // 下边框
            allStyle.setBorderLeft(BorderStyle.THIN);// 左边框
            allStyle.setBorderTop(BorderStyle.THIN);// 上边框
            allStyle.setBorderRight(BorderStyle.THIN);// 右边框
            allStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
            allStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            allStyle.setWrapText(true);//自动换行

            String[] sheetHeadTitle = new String[]{"省", "市", "区(县)", "地理id(虚拟ID)", "人员伤亡(重伤、死亡)", "时间段(白天、夜间)",
                    "破坏程度", "计算值(人)", "修正值(人)", "期望值（人）"};
            Sheet sheet = workbook.createSheet("人员伤亡");
            // 设置自动列宽
            for (int i = 0; i < sheetHeadTitle.length; i++) {
                sheet.autoSizeColumn(i);
                sheet.setColumnWidth(i, 20*256);
            }
            String[] values = null;
            BigDecimal expectValue = BigDecimal.ZERO;
            for (int i = 0; i < list.size() + 2; i++) {
                if (i > 1) {
                    values = CheckObjFields.objectChangeArray(list.get(i - 2));
                }
                Row row_i = sheet.createRow(i);
                for (int j = 0; j < sheetHeadTitle.length; j++) {
                    Cell celli_j = row_i.createCell(j, CellType.STRING);
                    if (i == 0) {
                        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, sheetHeadTitle.length - 1));
                        celli_j.setCellValue("人员伤亡");
                        celli_j.setCellStyle(allStyle);
                        break;
                    } else if (i == 1) {
                        celli_j.setCellValue(sheetHeadTitle[j]);
                    } else {
                        if (j == sheetHeadTitle.length-1) {
                            if ((i - 1) % 4 == 0) {
                                sheet.addMergedRegion(new CellRangeAddress(i - 3, i, j, j));
                                Row row = sheet.getRow(i - 3);
                                Cell cell = row.getCell(j);
                                expectValue = expectValue.add(new BigDecimal(values[j])).setScale(6,RoundingMode.HALF_DOWN);
                                cell.setCellValue((expectValue.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:expectValue) + "");
                                cell.setCellStyle(allStyle);
                                expectValue = BigDecimal.ZERO;
                            } else {
                                try{
                                    expectValue = expectValue.add(new BigDecimal(values[j])).setScale(6,RoundingMode.HALF_DOWN);
                                }catch (Exception e){
                                    e.printStackTrace();
                                }

                            }
                        } else {
                            if (values[j] == null) {
                                continue;
                            }
                            switch (values[j]){
                                case "rysw1":celli_j.setCellValue("重伤");break;
                                case "rysw2":celli_j.setCellValue("死亡");break;
                                case "sjd1":celli_j.setCellValue("白天");break;
                                case "sjd2":celli_j.setCellValue("夜晚");break;
                                default:celli_j.setCellValue(values[j]);
                            }
                        }
                    }
                    celli_j.setCellStyle(allStyle);
                }
                sheet.autoSizeColumn((short) i);
            }
            // 07版本
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("人员伤亡概率评估计算.xlsx", "UTF-8"));
            response.setCharacterEncoding("UTF-8");
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }

    //查询计算值
    @Override
    public Map<String, Object> queryCalculation(int curPage, int pageSize, String id, String casualties, String time, String years) {
        return casualtiesPERepository.queryCalculation(curPage, pageSize, id, casualties, time, years);
    }

    //修改概率P(t)修正值
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void updateCorrectionValue(CasualtiesPECalculation param) {
        //param.setExpectValue(param.getCorrectionValue().multiply(new BigDecimal(param.getChancePt())).setScale(2,RoundingMode.HALF_DOWN));
        //获取相同id的其他数据
//        List<CasualtiesPECalculation> list = casualtiesPERepository.getOtherConditionData(param.getAssessId(),param.getGeographyId(),param.getCasualties(),param.getTime(),param.getId());
//        BigDecimal result2 = list.stream()
//                // 将user对象的age取出来map为Bigdecimal
//                .map(CasualtiesPECalculation::getCorrectionValue)
//                // 使用reduce()聚合函数,实现累加器
//                .reduce(BigDecimal.ZERO,BigDecimal::add);
//        result2 = result2.add(param.getCorrectionValue());
//        param.setExpectValue(result2);
        param.setExpectValue(param.getCorrectionValue());
        casualtiesPERepository.updateCorrectionValue(param);
//        //批量修改
//        for (CasualtiesPECalculation casualtiesPECalculation : list) {
//            casualtiesPECalculation.setExpectValue(result2);
//            casualtiesPERepository.updateExpectValue(casualtiesPECalculation);
//        }
    }

    @Override
    public List<FxqhAssessPdQhResult> doZoning(CalculationTasks task) throws UnsupportedEncodingException, BizException {
        List<FxqhAssessPdQhResult> resultList = new ArrayList<>();
        Map<String, String> areaIdCodeMap = (Map<String, String>) JSON.parse((String) redisTemplate.opsForValue().get(FxfzConstants.CACHE_SYS_KEY + "areaIdCodeMap"));
        List<PCC> pccList = null;
//        if (task.getRadio2().equals("0")) {
        pccList = task.getList();
//        } else {
//            pccList = pccRepository.queryToponym(task.getId());
//        }
        String seiMode = null;
        if (task.getSeismicInputMode().contains("3")) {
            //发生概率
            seiMode = "0";
        } else if (task.getSeismicInputMode().contains("4")) {
            //超越概率
            seiMode = "1";
        } else {
            throw new RuntimeException("没有概率评估，不能进行概率评估风险区划！");
        }
        Map<String, Map<String, List<Map<String, Object>>>> listMapMap = new HashMap<>();
        Map<String, List<Map<String, Object>>> listMap = null;
        List<Map<String, Object>> mapList = null;
        List<Map<String, Object>> list = casualtiesPERepository.getSumByTaskId(task.getId());
        if(PlatformObjectUtils.isNotEmpty(list) &&list.size()>0){
            for (Map<String, Object> map : list) {
                String key1 = map.get("provinceName") + "-" + map.get("cityName") + "-" + map.get("countyName");
                if (listMapMap.containsKey(key1)) {
                    listMap = listMapMap.get(key1);
                } else {
                    listMap = new HashMap<>();
                }
                if (listMap.containsKey(map.get("years") + "")) {
                    mapList = listMap.get(map.get("years") + "");
                } else {
                    mapList = new ArrayList<>();
                }
                mapList.add(map);
                listMap.put(map.get("years") + "", mapList);
                listMapMap.put(key1, listMap);
            }
            // for (String seiMode : task.getSeismicInputMode().split(",")) {
            //     if (!seiMode.equals("3")) {
            //         continue;
            //     }
        }
        Map<String, List<Map<String, Object>>> listMap1 = null;
        List<Map<String, Object>> mapList1 = null;
        if(listMapMap.values().size()>0){
            for (PCC pcc : pccList) {
                listMap1 = listMapMap.get(pcc.getPpName() + "-" + pcc.getCityName() + "-" + pcc.getName());
                String divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(pcc.getPpName(), "UTF-8"),
                        URLEncoder.encode(pcc.getCityName(), "UTF-8"), URLEncoder.encode(pcc.getName(), "UTF-8"));
                String code = null;
                if (areaIdCodeMap==null||areaIdCodeMap.size()<1) {
                    code = sysAreaService.getDivisionCodeById(divisionIds.split("_")[2]);
                }else {
                    code = areaIdCodeMap.get(divisionIds.split("_")[2]);
                }
                String geom = jcsjRestManager.getGeomByCode(code,"3");
                if (geom == null) {
                    continue;
                    // throw new RuntimeException("未获取到" + pcc.getPpName() + pcc.getCityName() + pcc.getName() + "的空间数据！");
                }
                for (String years : task.getYear().split(",")) {
                    mapList1 = listMap1.get(years);
                    // List<Map<String, Object>> list = casualtiesPERepository.getSumByDivisionAndAssessCodes(pcc.getPpName(), pcc.getCityName(), pcc.getName(),
                    //         task.getId(), condition);
                    BigDecimal calculatedValue = BigDecimal.ZERO;
                    for (int i = 0; i < mapList1.size(); i++) {
                        Map<String, Object> map = mapList1.get(i);
                        calculatedValue = calculatedValue.add(BigDecimal.valueOf((Double) map.get("sum")));
                    }
                    FxqhAssessPdQhResult result = new FxqhAssessPdQhResult();
                    result.setProvince(pcc.getPpName());
                    result.setCity(pcc.getCityName());
                    result.setCounty(pcc.getName());
                    if ("新疆维吾尔自治区".equals(pcc.getPpName()) || "青海省".equals(pcc.getPpName()) || "西藏自治区".equals(pcc.getPpName())) {
                        result.setBorderlandFlag("1");
                    } else {
                        result.setBorderlandFlag("0");
                    }
                    if (mapList1.size() > 0) {
                        result.setCalculatedValue(calculatedValue);
                    } else {
                        result.setCalculatedValue(BigDecimal.ZERO);
                    }
                    // result.setCalculatedValue(calculatedValue);
                    result.setGeom(geom);
                    result.setId(UUIDGenerator.getUUID());
                    result.setTaskId(task.getId());
                    result.setEstimateObj("1");
                    result.setHouseDataFlag(task.getHouseDataFlag());
                    result.setCondition(years);
                    result.setSeismicInputMode(seiMode);
                    resultList.add(result);
                }
            }
        }
        // }
        return resultList;
    }

    //获取list
    private Map<String, Object> getList(Workbook workbook, String type, String id, String years, String code) throws UnsupportedEncodingException {
        String userID = PlatformSessionContext.getUserID();
        Map<String, Object> map = new HashMap<>();
        List<CasualtiesPECalculation> list = new ArrayList<>();
        Boolean mark = true;
//        if (type.equals("2")) {
//            mark = false;
//        }
        if (workbook != null) {
            //循环除了第一行的所有行
            /** 得到第一个sheet */
            Sheet sheet = workbook.getSheetAt(0);
            /** 得到Excel的行数 */
            int totalRows = sheet.getPhysicalNumberOfRows();
            HSSFDataFormatter hSSFDataFormatter = new HSSFDataFormatter();
            /** 循环Excel的行 从第4行开始*/
            for (int r = 2; r < totalRows; r++) {
                Row row = sheet.getRow(r);
                if (row == null) {
                    continue;
                }
                CasualtiesPECalculation obj = new CasualtiesPECalculation();
                if (mark) {
                    //按照省市县输入时校验
                    Map<String, Object> check = check(row, type);
                    //如果没有message
                    if (check.get("message") == null) {
                        //省
                        obj.setProvinceName(hSSFDataFormatter.formatCellValue(row.getCell(0)));
                        //市
                        obj.setCityName(hSSFDataFormatter.formatCellValue(row.getCell(1)));
                        //县
                        obj.setCountyName(hSSFDataFormatter.formatCellValue(row.getCell(2)));
                        //建筑物公里网格ID（建筑物单体ID）
                        obj.setGeographyId(hSSFDataFormatter.formatCellValue(row.getCell(3)));
                        //人员伤亡
                        obj.setCasualties(dictService.getKeyByDictCodeAndValue("rysw", hSSFDataFormatter.formatCellValue(row.getCell(4))));
                        //时间段
                        obj.setTime("白天".equals(row.getCell(5))?"sjd1":"sjd2");
                        //极限破坏(轻微,中等,严重,倒塌)
                        obj.setExtreme(hSSFDataFormatter.formatCellValue(row.getCell(6)));
                        //计算着(人)
                        Double aDouble = Double.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(7)));
                        obj.setCalculatedValue(new BigDecimal(aDouble));
                        //修改值(人)
                        obj.setCorrectionValue(new BigDecimal(Double.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(8)))));
                        obj.setDelFlag("0");
                        obj.setExpectValue(obj.getCalculatedValue());
                    } else {
                        return check;
                    }
                } else {
                    //按照坐标范围输入时校验
                    Map<String, Object> check = check2(row, type);
                    //如果没有message
                    if (check.get("message") == null) {
                        //经纬度坐标范围
                        obj.setCoordinateRange(hSSFDataFormatter.formatCellValue(row.getCell(0)));
                        //建筑物公里网格ID（建筑物单体ID）
                        obj.setGeographyId(hSSFDataFormatter.formatCellValue(row.getCell(1)));
                        //人员伤亡
                        obj.setCasualties(dictService.getKeyByDictCodeAndValue("rysw", hSSFDataFormatter.formatCellValue(row.getCell(2))));
                        //时间段
                        obj.setTime(dictService.getKeyByDictCodeAndValue("sjd", hSSFDataFormatter.formatCellValue(row.getCell(3))));
                        //极限破坏(轻微,中等,严重,倒塌)
                        obj.setExtreme(hSSFDataFormatter.formatCellValue(row.getCell(4)));
                        //计算着(人)
                        obj.setCalculatedValue(new BigDecimal(Double.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(5)))));
                        //修改值(人)
                        obj.setCorrectionValue(new BigDecimal(Double.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(6)))));
                        obj.setDelFlag("0");
                        obj.setExpectValue(obj.getCalculatedValue());
                    } else {
                        return check;
                    }
                }
                //评估记录id
                obj.setAssessId(id);
                //评估记录编号
                obj.setAssessCode(code);
                //主键id
                obj.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                //创建人
                obj.setCreateUser(userID);
                //创建时间
                obj.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                //T年
                obj.setYears(years);
                list.add(obj);
            }
        }
//        if(list.size()>0){
//            Map<String, List<CasualtiesPECalculation>> collect = list.stream().collect(Collectors.groupingBy(casualtiesPECalculation -> casualtiesPECalculation.getGeographyId()+"_"+casualtiesPECalculation.getCasualties()+"_"+casualtiesPECalculation.getTime()));
//            collect.forEach((k,v)->{
//                BigDecimal result2 = v.stream()
//                        // 将user对象的age取出来map为Bigdecimal
//                        .map(CasualtiesPECalculation::getCorrectionValue)
//                        // 使用reduce()聚合函数,实现累加器
//                        .reduce(BigDecimal.ZERO,BigDecimal::add);
//                for (CasualtiesPECalculation casualtiesPECalculation : v) {
//                    casualtiesPECalculation.setExpectValue(result2);
//                }
//            });
//        }
        map.put("list", list);
        return map;
    }

    //数据校验省市县
    private Map<String, Object> check(Row row, String type) throws UnsupportedEncodingException {
        HashMap<String, Object> map = new HashMap<>();
        HSSFDataFormatter hSSFDataFormatter = new HSSFDataFormatter();
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(0)))) {
            map.put("message", "省不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(1)))) {
            map.put("message", "市不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(2)))) {
            map.put("message", "县不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(3)))) {
            map.put("message", "建筑物公里网格ID（建筑物单体ID）不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(4)))) {
            map.put("message", "人员伤亡不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(5)))) {
            map.put("message", "时间段不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(6)))) {
            map.put("message", "极限破坏不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(7)))) {
            map.put("message", "计算值（人）不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(8)))) {
            map.put("message", "修正值（人）不能为空");
        }

        String province = hSSFDataFormatter.formatCellValue(row.getCell(0));
        String city = hSSFDataFormatter.formatCellValue(row.getCell(1));
        String county = hSSFDataFormatter.formatCellValue(row.getCell(2));
        // 根据省市县名称获得省市县id _ 分割
        String divisionIds = sysAreaService.getIdByCondition(
                URLEncoder.encode(province, "UTF-8"),
                URLEncoder.encode(city, "UTF-8"),
                URLEncoder.encode(county, "UTF-8"));
        if (divisionIds == null) {
            map.put("message", "省市县错误" + province + "_" + city + "_" + county);
        }
        String[] s = divisionIds.split("_");
        if (s.length != 3) {
            map.put("message", "省市县错误" + province + "_" + city + "_" + county);
        }
        return map;
    }

    //范围校验
    private Map<String, Object> check2(Row row, String type) throws UnsupportedEncodingException {
        HashMap<String, Object> map = new HashMap<>();
        HSSFDataFormatter hSSFDataFormatter = new HSSFDataFormatter();
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(0)))) {
            map.put("message", "坐标范围不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(1)))) {
            map.put("message", "建筑物公里网格ID（建筑物单体ID）不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(2)))) {
            map.put("message", "人员伤亡不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(3)))) {
            map.put("message", "时间段不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(4)))) {
            map.put("message", "极限破坏不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(5)))) {
            map.put("message", "计算值（人）不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(6)))) {
            map.put("message", "修正值（人）不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(7)))) {
            map.put("message", "概率P（1）计算值不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(8)))) {
            map.put("message", "概率P（1）修正值不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(9)))) {
            map.put("message", "概率值p(T)(用【概率P(1)修正值】进行计算）不能为空");
        }
        if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(10)))) {
            map.put("message", "期望值（人)不能为空");
        }
        return map;
    }

    @Override
    public List<Statistics> statistics(String taskId, String casualties, String time) {
        List<Statistics> list = new ArrayList<>();
        List<String> extremeList = extremeList();
        //获取评估任务关联的省市区县
        List<PCC> pccs = pccRepository.queryToponym(taskId);
        if(PlatformObjectUtils.isEmpty(pccs) || pccs.size() == 0){
            throw new RuntimeException("任务没有关联任何评估区域");
        }
        List<String> provinceList = pccs.stream().map(PCC::getPpName).distinct().collect(Collectors.toList());
        for (String province : provinceList) {
            List<String> cityList = pccs.stream().filter(pcc->province.equals(pcc.getPpName())).map(PCC::getCityName).distinct().collect(Collectors.toList());
            //根据省获取确定评估人员伤亡数据
            List<CasualtiesPECalculation>  resultList = casualtiesPERepository.getCasualtiesResult(taskId,province,casualties,time);
            if(PlatformObjectUtils.isNotEmpty(resultList) && resultList.size()>0){
                Map<String, List<CasualtiesPECalculation>> collectMap = resultList.stream().collect(Collectors.groupingBy(CasualtiesPECalculation::getExtreme));
                for (String extreme : extremeList) {
                    List<CasualtiesPECalculation> casualtiesPECalculations = collectMap.get(extreme);
                    //存在多个市 需要展示省
                    if (cityList.size() > 1) {
                        BigDecimal proTotal = casualtiesPECalculations.stream()
                                .map(CasualtiesPECalculation::getCorrectionValue) // 提取每个RiskAnalysisDeductDetail的Score字段
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        Statistics proStatistics = buildEntityData(province,proTotal,time,casualties,extreme);
                        List<Statistics> cityChildren = new ArrayList<>();
                        for (String city : cityList) {
                            List<String> countyList = pccs.stream().filter(pcc->city.equals(pcc.getCityName())).map(PCC::getName).distinct().collect(Collectors.toList());
                            BigDecimal cityTotal = casualtiesPECalculations.stream().filter(casualtiesPECalculation -> {
                                return city.equals(casualtiesPECalculation.getCityName());
                            }).map(CasualtiesPECalculation::getCorrectionValue).reduce(BigDecimal.ZERO, BigDecimal::add);
                            Statistics cityStatistics = buildEntityData(city,cityTotal,time,casualties,extreme);
                            List<Statistics> countyChildren = new ArrayList<>();
                            for (String county : countyList) {
                                BigDecimal countyTotal = casualtiesPECalculations.stream().filter(casualtiesPECalculation -> {
                                    return county.equals(casualtiesPECalculation.getCountyName());
                                }).map(CasualtiesPECalculation::getCorrectionValue).reduce(BigDecimal.ZERO, BigDecimal::add);
                                Statistics countyStatistics = buildEntityData(county,countyTotal,time,casualties,extreme);
                                countyChildren.add(countyStatistics);
                            }
                            cityStatistics.setChildren(countyChildren);
                            cityChildren.add(cityStatistics);
                        }
                        proStatistics.setChildren(cityChildren);
                        list.add(proStatistics);
                    }else{
                        List<String> countyList = pccs.stream().filter(pcc->cityList.get(0).equals(pcc.getCityName())).map(PCC::getName).distinct().collect(Collectors.toList());
                        if (countyList.size() > 1) {
                            BigDecimal cityTotal = casualtiesPECalculations.stream().filter(casualtiesPECalculation -> {
                                return cityList.get(0).equals(casualtiesPECalculation.getCityName());
                            }).map(CasualtiesPECalculation::getCorrectionValue).reduce(BigDecimal.ZERO, BigDecimal::add);
                            Statistics cityStatistics = buildEntityData(cityList.get(0),cityTotal,time,casualties,extreme);
                            List<Statistics> countyChildren = new ArrayList<>();
                            for (String county : countyList) {
                                BigDecimal countyTotal = casualtiesPECalculations.stream().filter(casualtiesPECalculation -> {
                                    return county.equals(casualtiesPECalculation.getCountyName());
                                }).map(CasualtiesPECalculation::getCorrectionValue).reduce(BigDecimal.ZERO, BigDecimal::add);
                                Statistics countyStatistics = buildEntityData(county,countyTotal,time,casualties,extreme);
                                countyChildren.add(countyStatistics);
                            }
                            cityStatistics.setChildren(countyChildren);
                            list.add(cityStatistics);
                        }else{
                            BigDecimal countyTotal = casualtiesPECalculations.stream().filter(casualtiesPECalculation -> {
                                return countyList.get(0).equals(casualtiesPECalculation.getCountyName());
                            }).map(CasualtiesPECalculation::getCorrectionValue).reduce(BigDecimal.ZERO, BigDecimal::add);
                            Statistics countyStatistics = buildEntityData(countyList.get(0),countyTotal,time,casualties,extreme);
                            list.add(countyStatistics);
                        }
                    }
                }
            }
        }
        return list;
    }

    private List<String> extremeList(){
        return  Arrays.asList("轻微破坏","中等破坏","严重破坏","倒塌");
    }
    private Statistics buildEntityData(String districtName,BigDecimal total,String time,String casualties,String extreme){
        Statistics statistics = new Statistics();
        statistics.setId(UUIDGenerator.getUUID()).setDistrictName(districtName).setValue(total).setTime("sjd1".equals(time)?"白天":"夜间")
                .setCasualties("rysw1".equals(casualties)?"重伤":"死亡").setExtreme(extreme);
        return statistics;
    }
}
